diff --git a/examples/cc/cc.g b/examples/cc/cc.g index 026877a..ced226a 100644 --- a/examples/cc/cc.g +++ b/examples/cc/cc.g @@ -1,443 +1,443 @@ -- Copyright (C) 2005 Roberto Raggi -- Copyright (C) 2009 Jonathan Schmidt-Dominé -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Library General Public License for more details. -- -- You should have received a copy of the GNU Library General Public License -- along with this library; see the file COPYING.LIB. If not, write to -- the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA. [: -#include -#include +#include +#include :] %parserclass (protected declaration) [: void expectedSymbol(cc::AstNode::AstNodeKind kind, const QString& name) { qWarning() << "In AstNode " << kind << ": Expected symbol " << name; } void expectedToken(int kind, enum TokenType token, const QString& name) { qWarning() << "In AstNode " << kind << ": Expected token " << name << " (" << token << ")";} struct ParserState { int ltCounter; }; ParserState m_state; :] %parser_declaration_header "ccast.h" ------------------------------------------------------------ -- T O K E N L I S T ------------------------------------------------------------ -- keywords: %token CASE ("case"), DEFAULT ("default"), IF ("if"), ELSE ("else"), SWITCH ("switch"), WHILE ("while"), DO ("do"), FOR ("for"), BREAK ("break"), CONTINUE ("continue"), GOTO ("goto"), RETURN ("return"), TYPEDEF ("typedef"), EXTERN ("extern"), STATIC ("static"), AUTO ("auto"), REGISTER ("register"), VOID ("void"), CHAR ("char"), SHORT ("short"), INT ("int"), LONG ("long"), FLOAT ("float"), DOUBLE ("double"), SIGNED ("signed"), UNSIGNED ("unsigned"), TYPEDEF_NAME ("pre-defined type specification"), STRUCT ("struct"), UNION ("union"), ENUM ("enum"), CONST ("const"), VOLATILE ("volatile") ;; -- seperators: %token LPAREN ("("), RPAREN (")"), LBRACE ("{"), RBRACE ("}"), LBRACKET ("["), RBRACKET ("]"), DOT ("."), ARROW ("->"), COLON (":"), COMMA (","), SEMICOLON (";") ;; -- operators: %token PLUS ("+"), MINUS ("-"), STAR ("*"), DIVIDE ("/"), REMAINDER ("%"), TILDE ("~"), AND ("&"), OR ("|"), XOR ("^"), NOT ("!"), SIZEOF ("sizeof"), PLUS_PLUS ("++"), MINUS_MINUS ("--"), LSHIFT ("<<"), RSHIFT (">>"), AND_AND ("&&"), OR_OR ("||"), QUESTION ("?"), EQUAL ("="), PLUS_EQUAL ("+="), MINUS_EQUAL ("-="), STAR_EQUAL ("*="), DIVIDE_EQUAL ("/="), REMAINDER_EQUAL ("%="), AND_EQUAL ("&="), OR_EQUAL ("|="), XOR_EQUAL ("^="), LSHIFT_EQUAL ("<<="), RSHIFT_EQUAL (">>="), EQUAL_EQUAL ("=="), NOT_EQUAL ("!="), LESS ("<"), GREATER (">"), LESS_EQUAL ("<="), GREATER_EQUAL (">="), ELLIPSIS ("...") ;; -- identifiers and literals: %token IDENTIFIER ("identifier"), STRING_LITERAL ("string literal"), X_CONSTANT ;; -- GCC extensions %token INLINE ("inline"), EXTENSION ("__extension__"), ASM ("asm") ;; ------------------------------------------------------------ -- E X T E R N A L D E C L A R A T I O N S ------------------------------------------------------------ (#ddeclaration=ddeclaration)* -> document ;; enum_specifier=enum_specifier SEMICOLON | struct_or_union_specifier=struct_or_union_specifier SEMICOLON | TYPEDEF typedef_d=typedef_d SEMICOLON | try/rollback(external_block=external_block) catch( value_declaration=value_declaration ) -> ddeclaration ;; typed_identifier ( SEMICOLON | try/rollback(function_definition=function_definition) catch( function_declaration=function_declaration )) -> value_declaration ;; EXTERN STRING_LITERAL LBRACE (#ddeclaration=ddeclaration)* RBRACE -> external_block ;; -- VOID -- | CHAR -- | SHORT -- | INT -- | LONG -- | FLOAT -- | DOUBLE ---> type_name_d ;; LPAREN type_attribute_identifier=type_attribute_identifier RPAREN (LPAREN (0 | (#function_pointer_parameter=function_pointer_parameter @ COMMA)) RPAREN | 0) | STAR type_attribute_identifier=type_attribute_identifier | type_attribute_identifier=type_attribute_identifier LBRACKET (0 | X_CONSTANT) RBRACKET | IDENTIFIER -> type_attribute_identifier ;; type_name=type_name type_attribute_identifier=type_attribute_identifier -> typed_identifier ;; typed_identifier=typed_identifier SEMICOLON -> variable_declaration ;; try/rollback(typed_identifier=typed_identifier) catch( type_name=type_name ) -> parameter ;; struct_or_union_specifier=struct_or_union_specifier | enum_specifier=enum_specifier | typed_identifier=typed_identifier -> typedef_d ;; (#statement = statement)* -> execution_block ;; LPAREN (0|#declaration_parameter=declaration_parameter @ COMMA) RPAREN (0|asm_against_mangling=asm_against_mangling) SEMICOLON -> function_declaration ;; typed_identifier=typed_identifier (0 | EQUAL constant_expression=constant_expression) | ELLIPSIS -> named_parameter ;; try/rollback(typed_identifier=typed_identifier (0 | EQUAL constant_expression=constant_expression)) catch( type_name=type_name ) | ELLIPSIS -> declaration_parameter ;; try/rollback(typed_identifier=typed_identifier) catch( type_name=type_name ) | ELLIPSIS -> function_pointer_parameter ;; LPAREN (#named_parameter=named_parameter @ COMMA) RPAREN LBRACE execution_block=execution_block RBRACE -> function_definition ;; -- (#external_declaration=external_declaration)* ---> translation_unit ;; #declaration_specifier=declaration_specifier (#declaration_specifier=declaration_specifier)* -> declaration_header ;; -- declaration_header=declaration_header variable_or_function=variable_or_function ---> external_declaration ;; -- declarator=declarator (COMMA #init_declarator=init_declarator @ COMMA SEMICOLON -- | SEMICOLON -- | ?[:is_fun_definition:] declaration* compound_statement -- | (#declaration=declaration)* compound_statement=compound_statement -- | initializer=initializer (COMMA #init_declarator=init_declarator)* SEMICOLON) ---> variable_or_function ;; ------------------------------------------------------------ -- GCC-STUFF ------------------------------------------------------------ STRING_LITERAL LPAREN IDENTIFIER -> asm_specifier ;; ASM (0 | VOLATILE) LPAREN (STRING_LITERAL*) (0 | COLON (#output_operands=asm_specifier @ COMMA) (0 | COLON (#input_operands=asm_specifier @ COMMA) (0 | COLON (STRING_LITERAL @ COMMA)))) -> inline_asm ;; EXTENSION LPAREN LBRACE execution_block RBRACE RPAREN -> ext_expression ;; ASM LPAREN STRING_LITERAL RPAREN -> asm_against_mangling ;; ------------------------------------------------------------ -- E X P R E S S I O N S ------------------------------------------------------------ identifier=IDENTIFIER | constant=constant | string_literal=STRING_LITERAL | LPAREN expression=expression RPAREN -> primary_expression ;; primary_expression=primary_expression (#postfix_expression_rest=postfix_expression_rest)* -> postfix_expression ;; (DOT | ARROW) IDENTIFIER | PLUS_PLUS | MINUS_MINUS | LPAREN (argument_expression_list=argument_expression_list | 0) RPAREN | LBRACKET expression=expression RBRACKET -> postfix_expression_rest ;; #assignment_expression=assignment_expression @ COMMA -> argument_expression_list ;; postfix_expression=postfix_expression | PLUS_PLUS unary_expression=unary_expression | MINUS_MINUS unary_expression=unary_expression | unary_operator cast_expression=cast_expression | SIZEOF LPAREN type_name=type_name RPAREN -> unary_expression ;; AND | STAR | PLUS | MINUS | TILDE | NOT -> unary_operator ;; LPAREN type_name=type_name RPAREN cast_expression=cast_expression | unary_expression=unary_expression -> cast_expression ;; #cast_expression=cast_expression @ (STAR | DIVIDE | REMAINDER) -> multiplicative_expression ;; #multiplicative_expression=multiplicative_expression @ (PLUS | MINUS) -> additive_expression ;; #additive_expression=additive_expression @ (LSHIFT | RSHIFT) -> shift_expression ;; #shift_expression=shift_expression @ (LESS | GREATER | LESS_EQUAL | GREATER_EQUAL) -> relational_expression ;; #relational_expression=relational_expression @ (EQUAL_EQUAL | NOT_EQUAL) -> equality_expression ;; #equality_expression=equality_expression @ AND -> AND_expression ;; #AND_expression=AND_expression @ XOR -> exclusive_OR_expression ;; #exclusive_OR_expression=exclusive_OR_expression @ OR -> inclusive_OR_expression ;; #inclusive_OR_expression=inclusive_OR_expression @ AND_AND -> logical_AND_expression ;; #logical_AND_expression=logical_AND_expression @ OR_OR -> logical_OR_expression ;; logical_OR_expression=logical_OR_expression (QUESTION expression COLON conditional_expression | 0) -> conditional_expression ;; #conditional_expression=conditional_expression @ assignment_operator -> assignment_expression ;; EQUAL | STAR_EQUAL | DIVIDE_EQUAL | REMAINDER_EQUAL | PLUS_EQUAL | MINUS_EQUAL | LSHIFT_EQUAL | RSHIFT_EQUAL | AND_EQUAL | XOR_EQUAL | OR_EQUAL -> assignment_operator ;; #assignment_expression=assignment_expression @ COMMA -> expression ;; conditional_expression=conditional_expression -> constant_expression ;; X_CONSTANT -> constant ;; ------------------------------------------------------------ -- S T A T E M E N T S ------------------------------------------------------------ IDENTIFIER COLON | labeled_statement=labeled_statement | compound_statement=compound_statement | expression_statement=expression_statement | selection_statement=selection_statement | iteration_statement=iteration_statement | jump_statement=jump_statement | inline_asm | SEMICOLON -> statement ;; CASE constant_expression=constant_expression COLON statement=statement | DEFAULT COLON statement=statement -> labeled_statement ;; LBRACE (#declaration=declaration)* (#statement=statement)* RBRACE -> compound_statement ;; expression=expression SEMICOLON -> expression_statement ;; IF LPAREN expression=expression RPAREN statement=statement (ELSE alternative_statement=statement | 0) | SWITCH LPAREN expression=expression RPAREN statement=statement -> selection_statement ;; WHILE LPAREN (expression=expression | ext_expression=ext_expression) RPAREN statement=statement | DO statement WHILE LPAREN expression=expression RPAREN SEMICOLON | FOR LPAREN (for_1=expression|for1_ext=ext_expression|0) SEMICOLON (for_2=expression|for2_ext=ext_expression|0) SEMICOLON (for_3=expression|for3_ext=ext_expression|0) RPAREN statement=statement -> iteration_statement ;; GOTO IDENTIFIER SEMICOLON | CONTINUE SEMICOLON | BREAK SEMICOLON | RETURN (expression=expression | 0) SEMICOLON -> jump_statement ;; ------------------------------------------------------------ -- D E C L A R A T I O N S ------------------------------------------------------------ #declaration_specifier=declaration_specifier (#declaration_specifier=declaration_specifier)* (#init_declarator=init_declarator @ COMMA | 0) SEMICOLON -> declaration ;; storage_class_specifier=storage_class_specifier | type_specifier=type_specifier | type_qualifier=type_qualifier -> declaration_specifier ;; declarator=declarator (EQUAL initializer=initializer | 0) -> init_declarator ;; TYPEDEF | EXTERN | STATIC | AUTO | REGISTER -> storage_class_specifier ;; VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | struct_or_union_specifier=struct_or_union_specifier | enum_specifier=enum_specifier | TYPEDEF_NAME -> type_specifier ;; -- EXTERN STRING_LITERAL LBRACE (#external_declaration=external_declaration)* RBRACE ---> external_block ;; (STRUCT | UNION) (IDENTIFIER LBRACE (#struct_declaration=struct_declaration)* RBRACE | LBRACE (#struct_declaration=struct_declaration)* RBRACE) -> struct_or_union_specifier ;; #specifier_qualifier=specifier_qualifier #specifier_qualifier=specifier_qualifier (#specifier_qualifier=specifier_qualifier*) (#struct_declarator=struct_declarator)* SEMICOLON -> struct_declaration ;; type_specifier=type_specifier | type_qualifier=type_qualifier -> specifier_qualifier ;; declarator=declarator (constant_expression=constant_expression | 0) | COLON constant_expression=constant_expression -> struct_declarator ;; ENUM (IDENTIFIER LBRACE #enumerator=enumerator @ COMMA RBRACE | LBRACE #enumerator=enumerator @ COMMA RBRACE) -> enum_specifier ;; IDENTIFIER (EQUAL constant_expression=constant_expression | 0) -> enumerator ;; CONST | VOLATILE -> type_qualifier ;; (pointer=pointer direct_declarator=direct_declarator | direct_declarator=direct_declarator) (#direct_declarator_rest=direct_declarator_rest)* | direct_declarator=direct_declarator -> declarator ;; IDENTIFIER | LPAREN declarator=declarator RPAREN -> direct_declarator ;; LBRACKET (constant_expression | 0) RBRACKET | LPAREN (IDENTIFIER @ COMMA | parameter_type_list=parameter_type_list | 0) RPAREN -> direct_declarator_rest ;; STAR (#type_qualifier=type_qualifier | STAR)* -> pointer ;; (#parameter_declaration=parameter_declaration | ELLIPSIS) @ COMMA | 0 -> parameter_type_list ;; #declaration_specifier=declaration_specifier (#declaration_specifier=declaration_specifier)* (declarator=declarator | abstract_declarator=abstract_declarator | 0) -> parameter_declaration ;; #specifier_qualifier=specifier_qualifier (#specifier_qualifier=specifier_qualifier)* -> type_name ;; (pointer=pointer #direct_abstract_declarator=direct_abstract_declarator | #direct_abstract_declarator=direct_abstract_declarator) (#direct_abstract_declarator=direct_abstract_declarator)* -> abstract_declarator ;; LPAREN (abstract_declarator=abstract_declarator | parameter_type_list=parameter_type_list) RPAREN | LBRACKET (constant_expression | 0) RBRACKET -> direct_abstract_declarator ;; assignment_expression=assignment_expression | LBRACE #initializer=initializer (COMMA (#initializer=initializer | 0))* RBRACE -> initializer ;; [: namespace cc { Parser::ParserState *Parser::copyCurrentState() { ParserState *state = new ParserState(); state->ltCounter = m_state.ltCounter; return state; } void Parser::restoreState( Parser::ParserState *state ) { m_state.ltCounter = state->ltCounter; } }; :] diff --git a/examples/cc/cc.ll b/examples/cc/cc.ll index 8ce2585..d3c16e7 100644 --- a/examples/cc/cc.ll +++ b/examples/cc/cc.ll @@ -1,325 +1,325 @@ %{ /*-- Copyright (C) 2009 Jonathan Schmidt-Dominé -- Derived from the KDevelop-Java-Lexer -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Library General Public License for more details. -- -- You should have received a copy of the GNU Library General Public License -- along with this library; see the file COPYING.LIB. If not, write to -- the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA.*/ %} %option c++ %option yyclass="cc::Lexer" %option noyywrap %{ #define DONT_INCLUDE_FLEXLEXER #include "lexer.h" -#include +#include %} /* UTF-8 sequences, generated with the Unicode.hs script from * http://lists.gnu.org/archive/html/help-flex/2005-01/msg00043.html */ /* \u0024, \u0041-\u005a, \u005f, \u0061-\u007a: one byte in UTF-8 */ Letter1 [A-Za-z_$] /* \u00c0-\u00d6, \u00d8-\u00f6, \u00f8-\u00ff */ Letter2 [\xC3]([\x80-\x96]|[\x98-\xB6]|[\xB8-\xBF]) /* \u0100-\u1fff */ Letter3 [\xC4-\xDF][\x80-\xBF]|([\xE0][\xA0-\xBF]|[\xE1][\x80-\xBF])[\x80-\xBF] /* \u3040-\u318f */ Letter4 [\xE3]([\x86][\x80-\x8F]|[\x81-\x85][\x80-\xBF]) /* \u3300-\u337f */ Letter5 [\xE3][\x8C-\x8D][\x80-\xBF] /* \u3400-\u3d2d */ Letter6 [\xE3](\xB4[\x80-\xAD]|[\x90-\xB3][\x80-\xBF]) /* \u4e00-\u9fff */ Letter7 ([\xE4][\xB8-\xBF]|[\xE5-\xE9][\x80-\xBF])[\x80-\xBF] /* \uf900-\ufaff */ Letter8 [\xEF][\xA4-\xAB][\x80-\xBF] Letter {Letter1}|{Letter2}|{Letter3}|{Letter4}|{Letter5}|{Letter6}|{Letter7}|{Letter8} /* \u0030-\u0039: ISO-LATIN-1 digits */ Digit1 [0-9] /* \u0660-\u0669, \u06f0-\u06f9: Arabic-Indic and extended Ar.-Indic digits */ Digit2 [\xD9][\xA0-\xA9]|[\xDB][\xB0-\xB9] /* \u0966-\u096f, \u09e6-\u09ef: Devanagari digits */ Digit3 [\xE0]([\xA5]|[\xA7])[\xA6-\xAF] /* \u0a66-\u0a6f, \u0ae6-\u0aef */ Digit4 [\xE0]([\xA9]|[\xAB])[\xA6-\xAF] /* \u0b66-\u0b6f, \u0be7-\u0bef */ Digit5 [\xE0]([\xAD][\xA6-\xAF]|[\xAF][\xA7-\xAF]) /* \u0c66-\u0c6f, \u0ce6-\u0cef, \u0d66-\u0d6f */ Digit6 [\xE0]([\xB1]|[\xB3]|[\xB5])[\xA6-\xAF] /* \u0e50-\u0e59, \u0ed0-\u0ed9 */ Digit7 [\xE0]([\xB9]|[\xBB])[\x90-\x99] /* \u1040-\u1049 */ Digit8 [\xE1][\x81][\x80-\x89] /* \uff10-\uff19: Fullwidth digits */ Digit9 [\xEF][\xBC][\x90-\x99] /* \u0080-\uffff */ Multibyte1 ([\xC2-\xDF]|[\xE0][\xA0-\xBF]|[\xE1-\xEF][\x80-\xBF])[\x80-\xBF] /* \u10000-\u1fffff */ Multibyte2 ([\xF0][\x90-\xBF]|[\xF1-\xF7][\x80-\xBF])[\x80-\xBF][\x80-\xBF] /* \u200000-\u3ffffff */ Multibyte3 ([\xF8][\x88-\xBF]|[\xF9-\xFB][\x80-\xBF])[\x80-\xBF][\x80-\xBF][\x80-\xBF] /* \u4000000-\u7fffffff */ Multibyte4 ([\xFC][\x84-\xBF]|[\xFD][\x80-\xBF])[\x80-\xBF][\x80-\xBF][\x80-\xBF] /* Any multi-byte Unicode character. Single-byte ones are just . in lex. */ Multibyte {Multibyte1}|{Multibyte2}|{Multibyte3}|{Multibyte4} /* non-Unicode stuff */ HexDigit [0-9a-fA-F] Digit {Digit1}|{Digit2}|{Digit3}|{Digit4}|{Digit5}|{Digit6}|{Digit7}|{Digit8}|{Digit9} OctalDigit [0-7] NonZeroDigit [1-9] UnicodeEscape [\\][u]+{HexDigit}{HexDigit}{HexDigit}{HexDigit} OctalEscape [\\]{OctalDigit}({Digit}({Digit})?)? SimpleEscape [\\]([']|["]|[\\]|[rnbft]) Escape {SimpleEscape}|{UnicodeEscape}|{OctalEscape} IntSuffix [Ll] DecimalNum ([0]|{NonZeroDigit}{Digit}*){IntSuffix}? OctalNum [0]{OctalDigit}+{IntSuffix}? HexNum [0][xX]{HexDigit}+{IntSuffix}? IntegerLiteral {DecimalNum}|{OctalNum}|{HexNum} Sign [+-] FloatSuffix [fF]|[dD] SignedInt {Sign}?{Digit}+ DecimalExponent [eE]{SignedInt}? BinaryExponent [pP]{SignedInt}? Float1 {Digit}+[\.]{Digit}*{DecimalExponent}?{FloatSuffix}? Float2 [\.]{Digit}+{DecimalExponent}?{FloatSuffix}? Float3 {Digit}+{DecimalExponent}{FloatSuffix}? Float4 {Digit}+{DecimalExponent}?{FloatSuffix} HexFloatNum [0][xX]{HexDigit}*[\.]{HexDigit}+ HexFloat1 {HexNum}[\.]?{BinaryExponent}{FloatSuffix}? HexFloat2 {HexFloatNum}{BinaryExponent}{FloatSuffix}? FloatingPoint {Float1}|{Float2}|{Float3}|{Float4}|{HexFloat1}|{HexFloat2} %x IN_BLOCKCOMMENT %% /* whitespace, newlines, preprocessor-statements and comments */ [ \f\t]+ /* skip */ ; [\n] /* skip */ ; "//"[^\n]* /* line comments, skip */ ; "#"[^\n]* /* preprocessor statement, skip */ ; "/*" BEGIN(IN_BLOCKCOMMENT); { [^*\n]* /* eat anything that's not a '*' */ ; "*"+[^*/\n]* /* eat up '*'s that are not followed by slashes or newlines */; [\n] /* skip */ ; "*"+"/" BEGIN(INITIAL); <> { qWarning() << "Encountered end of file in an unclosed block comment"; return Parser::Token_EOF; } } /* separators */ "(" return Parser::Token_LPAREN; ")" return Parser::Token_RPAREN; "{" return Parser::Token_LBRACE; "}" return Parser::Token_RBRACE; "[" return Parser::Token_LBRACKET; "]" return Parser::Token_RBRACKET; "," return Parser::Token_COMMA; ";" return Parser::Token_SEMICOLON; "." return Parser::Token_DOT; "->" return Parser::Token_ARROW; ":" return Parser::Token_COLON; /* operators */ "?" return Parser::Token_QUESTION; "!" return Parser::Token_NOT; "~" return Parser::Token_TILDE; "==" return Parser::Token_EQUAL_EQUAL; "<" return Parser::Token_LESS; "<=" return Parser::Token_LESS_EQUAL; ">" return Parser::Token_GREATER; ">=" return Parser::Token_GREATER_EQUAL; "!=" return Parser::Token_NOT_EQUAL; "&&" return Parser::Token_AND_AND; "||" return Parser::Token_OR_OR; "++" return Parser::Token_PLUS_PLUS; "--" return Parser::Token_MINUS_MINUS; "=" return Parser::Token_EQUAL; "+" return Parser::Token_PLUS; "+=" return Parser::Token_PLUS_EQUAL; "-" return Parser::Token_MINUS; "-=" return Parser::Token_MINUS_EQUAL; "*" return Parser::Token_STAR; "*=" return Parser::Token_STAR_EQUAL; "/" return Parser::Token_DIVIDE; "/=" return Parser::Token_DIVIDE_EQUAL; "&" return Parser::Token_AND; "&=" return Parser::Token_AND_EQUAL; "|" return Parser::Token_OR; "|=" return Parser::Token_OR_EQUAL; "^" return Parser::Token_XOR; "^=" return Parser::Token_XOR_EQUAL; "%" return Parser::Token_REMAINDER; "%=" return Parser::Token_REMAINDER_EQUAL; "<<" return Parser::Token_LSHIFT; "<<=" return Parser::Token_LSHIFT_EQUAL; ">>" return Parser::Token_RSHIFT; ">>=" return Parser::Token_RSHIFT_EQUAL; "..." return Parser::Token_ELLIPSIS; /* keywords */ "break" return Parser::Token_BREAK; "case" return Parser::Token_CASE; "continue" return Parser::Token_CONTINUE; "default" return Parser::Token_DEFAULT; "do" return Parser::Token_DO; "else" return Parser::Token_ELSE; "enum" return Parser::Token_ENUM; "for" return Parser::Token_FOR; "goto" return Parser::Token_GOTO; "if" return Parser::Token_IF; "return" return Parser::Token_RETURN; "switch" return Parser::Token_SWITCH; "while" return Parser::Token_WHILE; "static" return Parser::Token_STATIC; "volatile" return Parser::Token_VOLATILE; "__volatile__" return Parser::Token_VOLATILE; "const" return Parser::Token_CONST; "typedef" return Parser::Token_TYPEDEF; "extern" return Parser::Token_EXTERN; "auto" return Parser::Token_AUTO; "register" return Parser::Token_REGISTER; "void" return Parser::Token_VOID; "int" return Parser::Token_INT; "char" return Parser::Token_CHAR; "short" return Parser::Token_SHORT; "long" return Parser::Token_LONG; "signed" return Parser::Token_SIGNED; "unsigned" return Parser::Token_UNSIGNED; "float" return Parser::Token_FLOAT; "double" return Parser::Token_DOUBLE; "union" return Parser::Token_UNION; "asm" return Parser::Token_ASM; "__asm__" return Parser::Token_ASM; "__extension__" return Parser::Token_EXTENSION; "__inline" return Parser::Token_INLINE; "inline" return Parser::Token_INLINE; /* characters and strings (C with unicode-support) */ [']({Escape}|{Multibyte}|[^\\\n\'])['] return Parser::Token_X_CONSTANT; [']({Escape}|{Multibyte}|[\\][^\\\n\']|[^\\\n\'])*([\\]?[\n]|[']) { qWarning() << QString("Invalid character literal: %1").arg(yytext); return Parser::Token_X_CONSTANT; } ["]({Escape}|{Multibyte}|[^\\\n\"])*["] return Parser::Token_STRING_LITERAL; ["]({Escape}|{Multibyte}|[\\][^\\\n\"]|[^\\\n\"])*([\\]?[\n]|["]) { qWarning() << QString("Invalid string literal: %1").arg(yytext); return Parser::Token_STRING_LITERAL; } /* identifiers and number literals */ {Letter}({Letter}|{Digit})* return Parser::Token_IDENTIFIER; {IntegerLiteral} return Parser::Token_X_CONSTANT; {FloatingPoint} return Parser::Token_X_CONSTANT; /* everything else is not a valid lexeme */ . { qWarning() << "INVALID TOKEN"; exit(-1); } %% namespace cc { Lexer::Lexer( Parser *parser, char *contents ) { restart( parser, contents ); } void Lexer::restart( Parser *parser, char *contents ) { m_parser = parser; m_locationTable = parser->tokenStream->locationTable(); m_contents = contents; m_tokenBegin = m_tokenEnd = 0; m_currentOffset = 0; // check for and ignore the UTF-8 byte order mark unsigned char *ucontents = (unsigned char *) m_contents; if ( ucontents[0] == 0xEF && ucontents[1] == 0xBB && ucontents[2] == 0xBF ) { m_tokenBegin = m_tokenEnd = 3; m_currentOffset = 3; } yyrestart(NULL); BEGIN(INITIAL); // is not set automatically by yyrestart() } // reads a character, and returns 1 as the number of characters read // (or 0 when the end of the string is reached) int Lexer::LexerInput( char *buf, int /*max_size*/ ) { int c = m_contents[ m_currentOffset++ ]; switch(c) { case '\r': c = '\n'; // only have one single line break character: '\n' if ( m_contents[m_currentOffset + 1] == '\n' ) { m_currentOffset++; m_tokenEnd++; } // fall through case '\n': m_locationTable->newline( m_currentOffset - 1 ); break; default: break; } return (c == 0) ? 0 : (buf[0] = c, 1); } } // end of namespace cc diff --git a/examples/cc/cclexer.cpp b/examples/cc/cclexer.cpp index a2c60f6..6fe9d1d 100644 --- a/examples/cc/cclexer.cpp +++ b/examples/cc/cclexer.cpp @@ -1,4368 +1,4368 @@ #line 2 "cclexer.cpp" #line 4 "cclexer.cpp" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 39 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer yyFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include #include #include #include #include /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #define YY_INTERACTIVE #include int yyFlexLexer::yywrap() { return 1; } int yyFlexLexer::yylex() { LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" ); return 0; } #define YY_DECL int cc::Lexer::yylex() /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 100 #define YY_END_OF_BUFFER 101 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[746] = { 0, 0, 0, 6, 6, 101, 99, 1, 2, 22, 99, 4, 96, 49, 43, 99, 10, 11, 39, 35, 16, 37, 18, 41, 97, 97, 20, 17, 25, 34, 27, 21, 14, 15, 47, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 12, 45, 13, 23, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 6, 8, 7, 1, 29, 0, 95, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 30, 44, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 32, 36, 33, 38, 19, 0, 98, 0, 0, 0, 0, 0, 5, 3, 42, 98, 97, 0, 98, 98, 97, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 51, 26, 24, 28, 53, 48, 96, 96, 96, 96, 96, 96, 96, 96, 60, 96, 96, 96, 96, 96, 96, 65, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 46, 31, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 98, 98, 0, 0, 0, 0, 0, 97, 0, 98, 98, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 54, 96, 96, 96, 96, 87, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 63, 96, 96, 78, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 98, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, 0, 97, 96, 96, 96, 96, 75, 96, 57, 79, 96, 96, 96, 96, 61, 62, 96, 96, 64, 96, 81, 96, 96, 96, 96, 96, 96, 96, 96, 96, 77, 96, 96, 96, 96, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 98, 98, 0, 0, 98, 98, 0, 0, 0, 0, 0, 96, 96, 96, 96, 56, 72, 96, 96, 96, 96, 84, 96, 96, 96, 80, 96, 96, 96, 96, 86, 96, 96, 68, 96, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 98, 0, 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 96, 96, 96, 96, 96, 85, 74, 91, 96, 66, 82, 69, 67, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 88, 96, 96, 96, 96, 59, 96, 73, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 96, 90, 96, 58, 76, 83, 70, 0, 96, 96, 96, 96, 96, 96, 96, 71, 89, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 20, 21, 21, 22, 23, 24, 25, 26, 27, 1, 28, 28, 28, 29, 30, 31, 7, 7, 7, 7, 7, 32, 7, 7, 7, 33, 7, 7, 7, 7, 7, 7, 7, 34, 7, 7, 35, 36, 37, 38, 39, 1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 7, 49, 50, 51, 52, 53, 54, 7, 55, 56, 57, 58, 59, 60, 61, 62, 7, 63, 64, 65, 66, 1, 67, 68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 75, 74, 74, 76, 76, 76, 76, 76, 76, 76, 77, 78, 78, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 102, 102, 102, 1, 1, 105, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 107, 109, 107, 107, 107, 107, 110, 111, 112, 113, 114, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 116, 117, 118, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 121, 122, 1, 1 } ; static yyconst flex_int32_t yy_meta[123] = { 0, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 5, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 6, 7, 7, 7, 7, 6, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 10, 10, 11, 10, 10, 10, 10, 10, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[800] = { 0, 0, 0, 120, 121, 2366, 8770, 2363, 8770, 2339, 132, 0, 106, 2338, 119, 252, 8770, 8770, 2334, 115, 8770, 116, 150, 118, 358, 159, 8770, 8770, 114, 2329, 120, 8770, 8770, 8770, 2319, 186, 91, 109, 112, 119, 123, 142, 121, 148, 143, 111, 217, 115, 114, 144, 147, 8770, 160, 8770, 8770, 0, 0, 146, 185, 395, 2274, 235, 211, 0, 235, 0, 8770, 143, 2339, 8770, 497, 8770, 8770, 390, 617, 673, 273, 702, 382, 734, 257, 769, 166, 0, 314, 397, 0, 0, 300, 421, 794, 2268, 336, 336, 0, 442, 8770, 8770, 8770, 896, 8770, 529, 1016, 1072, 483, 1101, 521, 1133, 391, 1168, 204, 8770, 8770, 8770, 8770, 8770, 8770, 2318, 881, 543, 537, 557, 2266, 2228, 8770, 0, 8770, 914, 931, 1256, 8770, 951, 8770, 1262, 581, 575, 1226, 2263, 2226, 1305, 597, 820, 1287, 2260, 2223, 2301, 8770, 8770, 8770, 2296, 8770, 523, 2269, 2262, 2274, 2261, 2276, 2258, 2264, 2248, 2241, 2238, 2238, 2241, 2238, 2235, 0, 151, 2238, 153, 2236, 2242, 2247, 2237, 2230, 242, 239, 2235, 8770, 8770, 0, 0, 1366, 0, 985, 0, 1255, 2063, 0, 231, 869, 0, 1331, 0, 0, 0, 0, 0, 260, 0, 0, 205, 8770, 1480, 1600, 1720, 1840, 1960, 2080, 2136, 2174, 0, 0, 0, 1339, 0, 1349, 2062, 0, 277, 964, 0, 1375, 0, 0, 0, 0, 0, 320, 2276, 8770, 1448, 2396, 2452, 1387, 2481, 1440, 2513, 473, 2548, 345, 2650, 2770, 2890, 1507, 2946, 2984, 3022, 3060, 8770, 8770, 1539, 1488, 1523, 1533, 1542, 1554, 394, 1289, 459, 0, 1637, 8770, 1655, 1438, 1594, 1686, 2072, 2029, 8770, 935, 1707, 8770, 1459, 1697, 1805, 2064, 2027, 1884, 1890, 1716, 1763, 1883, 1892, 1902, 499, 1592, 1914, 1924, 1934, 1943, 1953, 502, 1662, 521, 8770, 8770, 2028, 2261, 382, 338, 2069, 380, 196, 503, 511, 512, 354, 315, 539, 589, 598, 404, 2068, 448, 150, 2067, 230, 596, 846, 848, 412, 866, 892, 861, 595, 916, 885, 868, 918, 2294, 2056, 2668, 1970, 1993, 3085, 1996, 2014, 0, 1985, 1934, 2288, 3187, 3243, 2036, 3272, 2052, 3304, 916, 3339, 931, 3441, 3561, 2340, 3617, 3655, 3692, 3794, 1977, 3850, 3888, 1903, 1882, 1881, 3990, 4110, 4230, 2635, 4334, 4372, 4410, 4505, 4555, 2621, 4593, 4631, 4668, 2767, 4706, 4744, 4782, 2337, 2638, 2219, 2318, 2642, 1873, 1835, 2797, 2341, 2828, 2267, 2736, 2859, 1870, 1833, 2777, 2880, 2890, 2899, 3110, 951, 2732, 972, 3120, 3130, 3141, 3150, 3160, 977, 2783, 980, 3438, 3465, 1261, 3483, 3977, 4008, 1223, 912, 1248, 1267, 1875, 917, 1856, 1855, 1021, 1018, 1272, 1302, 1840, 1835, 1234, 1313, 1833, 594, 1831, 1333, 1258, 1319, 886, 1330, 1290, 977, 1236, 1019, 1829, 1351, 1020, 4028, 1827, 3367, 3436, 4807, 1818, 3486, 4047, 3492, 0, 3517, 1796, 0, 1341, 3471, 1393, 4909, 5029, 5149, 3812, 5253, 5291, 5329, 5431, 5551, 3765, 5607, 5645, 5682, 5784, 3530, 3720, 3791, 3804, 4084, 3933, 4110, 4121, 4261, 3950, 4067, 5904, 6024, 4214, 6080, 6118, 6155, 6257, 4128, 6313, 6351, 4511, 4161, 4287, 4476, 517, 1774, 6446, 4240, 4500, 4513, 4835, 4848, 4313, 4879, 4890, 4958, 6496, 0, 4921, 4952, 4968, 4982, 4992, 1402, 4539, 1410, 5002, 5012, 5022, 5031, 5041, 1414, 4923, 1418, 5191, 5418, 5450, 1419, 4024, 5454, 8770, 5075, 5102, 5406, 1809, 1771, 5485, 5771, 1453, 1458, 1830, 1829, 1481, 1512, 1822, 1502, 1821, 1820, 1363, 1517, 1812, 1310, 288, 1437, 1800, 1780, 1626, 1486, 1777, 5802, 5140, 5154, 5367, 1737, 0, 1575, 5146, 1625, 5819, 6598, 6718, 5713, 6774, 6812, 6849, 6951, 5167, 7007, 7045, 7147, 7267, 0, 5427, 5488, 0, 5782, 5874, 5891, 7387, 6009, 7507, 7627, 5904, 7683, 7721, 7758, 7860, 5522, 5981, 5994, 6223, 6236, 5232, 6262, 6188, 7980, 5205, 5360, 6452, 6269, 6418, 6431, 6444, 6457, 6528, 6555, 6566, 8093, 6634, 6637, 6652, 4168, 7134, 8770, 5744, 5855, 6640, 1714, 1647, 6601, 6686, 6874, 6913, 6923, 1666, 5784, 1681, 1460, 1633, 1652, 1680, 1523, 1705, 1655, 1653, 1629, 1628, 1610, 1591, 1560, 1539, 1348, 1522, 1513, 7165, 6997, 5961, 6950, 7129, 1705, 1460, 7285, 5084, 7079, 7202, 7329, 7100, 7121, 7357, 7368, 7279, 7153, 7375, 8207, 7443, 7388, 7431, 7444, 7464, 7477, 7494, 7514, 7525, 7845, 7612, 7639, 7814, 7824, 7834, 7601, 7844, 1708, 7604, 1734, 7919, 1485, 1711, 1428, 1635, 1324, 1287, 1733, 1267, 1488, 1252, 8012, 7978, 7991, 8059, 8072, 8085, 7911, 8111, 8137, 8225, 8087, 8207, 8242, 1731, 1236, 1710, 1019, 977, 951, 949, 8260, 1769, 887, 1717, 1775, 1818, 1819, 1828, 557, 494, 8770, 8358, 8369, 8380, 528, 8391, 8397, 8402, 8408, 8413, 8417, 8428, 8439, 8450, 8461, 443, 8467, 8472, 8478, 8483, 8487, 8498, 8509, 8515, 8521, 8527, 8533, 8539, 8547, 8558, 8569, 8580, 8586, 8592, 8598, 8604, 8610, 8618, 8629, 260, 8635, 8641, 8652, 8663, 8674, 8680, 8686, 8697, 8708, 8719, 154, 8725, 8736, 8747, 8758 } ; static yyconst flex_int16_t yy_def[800] = { 0, 745, 1, 746, 746, 745, 745, 745, 745, 745, 747, 748, 749, 745, 745, 750, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 749, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 745, 745, 745, 745, 751, 752, 752, 752, 745, 753, 754, 745, 755, 745, 756, 745, 757, 745, 745, 747, 745, 745, 758, 747, 74, 75, 75, 77, 77, 79, 79, 81, 759, 760, 760, 761, 762, 762, 762, 745, 763, 764, 745, 765, 745, 745, 745, 745, 766, 745, 766, 766, 102, 103, 103, 105, 105, 107, 107, 109, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 767, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 745, 745, 85, 85, 85, 768, 768, 184, 184, 186, 184, 768, 768, 769, 745, 770, 771, 772, 770, 770, 745, 773, 774, 774, 745, 775, 776, 776, 775, 776, 776, 208, 208, 85, 85, 777, 777, 214, 214, 216, 214, 777, 777, 778, 745, 779, 780, 781, 779, 779, 745, 782, 745, 782, 782, 232, 233, 233, 235, 235, 237, 237, 239, 782, 782, 782, 243, 239, 239, 239, 239, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 783, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 784, 784, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 785, 785, 745, 786, 745, 330, 298, 298, 787, 787, 342, 343, 343, 345, 345, 347, 347, 349, 788, 788, 352, 352, 354, 354, 787, 352, 352, 352, 298, 298, 298, 789, 789, 789, 366, 366, 368, 368, 366, 368, 372, 372, 374, 374, 366, 374, 374, 374, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 790, 790, 745, 791, 745, 449, 790, 457, 457, 459, 457, 790, 790, 745, 792, 792, 792, 467, 467, 469, 469, 793, 793, 473, 473, 475, 475, 793, 473, 473, 473, 473, 473, 473, 473, 473, 467, 473, 473, 794, 794, 491, 491, 493, 493, 794, 491, 491, 491, 496, 491, 491, 493, 495, 495, 496, 491, 491, 491, 491, 491, 491, 491, 491, 496, 491, 516, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 795, 795, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 796, 796, 796, 572, 571, 796, 796, 745, 547, 797, 797, 580, 580, 582, 582, 797, 580, 580, 580, 798, 798, 590, 590, 590, 590, 590, 590, 590, 798, 585, 799, 799, 601, 601, 603, 603, 799, 601, 601, 601, 601, 601, 601, 601, 601, 799, 601, 601, 615, 601, 601, 601, 601, 601, 601, 601, 601, 615, 615, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 585, 580, 580, 582, 584, 584, 585, 580, 580, 580, 580, 580, 580, 580, 580, 585, 580, 580, 798, 615, 601, 601, 601, 601, 601, 601, 601, 601, 615, 615, 615, 745, 745, 745, 745, 745, 745, 745, 745, 745, 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, 585, 580, 580, 580, 580, 580, 580, 580, 580, 585, 585, 615, 745, 547, 547, 547, 547, 547, 547, 547, 585, 547, 547, 547, 547, 547, 547, 547, 547, 547, 0, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745 } ; static yyconst flex_int16_t yy_nxt[8893] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 12, 12, 12, 12, 12, 12, 12, 32, 6, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 12, 43, 12, 44, 12, 12, 12, 12, 45, 46, 47, 48, 49, 50, 12, 12, 51, 52, 53, 54, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 55, 56, 57, 58, 59, 60, 6, 61, 62, 63, 64, 6, 6, 6, 6, 6, 6, 66, 66, 85, 85, 85, 97, 112, 84, 124, 114, 67, 67, 71, 125, 72, 145, 146, 113, 115, 116, 126, 98, 148, 149, 152, 84, 153, 84, 84, 155, 84, 84, 169, 201, 84, 84, 156, 84, 202, 84, 158, 154, 157, 175, 117, 73, 118, 118, 118, 159, 160, 165, 161, 127, 174, 139, 139, 139, 84, 84, 84, 162, 178, 84, 84, 130, 131, 130, 132, 163, 166, 177, 164, 168, 176, 435, 318, 167, 315, 130, 131, 130, 85, 85, 85, 316, 132, 319, 84, 86, 87, 88, 89, 90, 91, 201, 92, 93, 94, 95, 202, 179, 151, 182, 182, 182, 182, 182, 182, 182, 210, 210, 210, 423, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 100, 84, 84, 119, 120, 121, 122, 100, 84, 170, 171, 123, 140, 141, 142, 143, 248, 248, 248, 172, 144, 436, 173, 182, 182, 182, 182, 182, 182, 182, 182, 182, 327, 101, 328, 325, 84, 86, 87, 88, 89, 90, 91, 326, 92, 93, 94, 95, 191, 191, 191, 192, 182, 182, 182, 193, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, 197, 209, 209, 209, 209, 209, 209, 659, 195, 84, 85, 85, 85, 129, 129, 129, 198, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 212, 212, 212, 429, 102, 102, 102, 102, 102, 103, 104, 104, 104, 104, 104, 104, 105, 106, 107, 108, 109, 110, 127, 84, 128, 128, 129, 212, 212, 212, 212, 212, 212, 212, 130, 131, 130, 132, 421, 133, 71, 428, 70, 85, 85, 85, 84, 204, 130, 131, 130, 221, 221, 221, 222, 132, 205, 205, 223, 370, 370, 370, 84, 85, 85, 85, 133, 86, 87, 88, 89, 90, 91, 70, 92, 93, 94, 95, 204, 225, 422, 420, 204, 226, 226, 226, 226, 226, 84, 204, 84, 433, 204, 84, 204, 206, 208, 208, 208, 208, 208, 208, 208, 208, 208, 247, 247, 247, 247, 247, 247, 440, 84, 134, 135, 136, 137, 118, 118, 118, 84, 138, 183, 183, 184, 183, 184, 183, 185, 183, 185, 183, 186, 183, 187, 183, 188, 188, 183, 188, 183, 183, 183, 189, 183, 189, 183, 71, 434, 72, 86, 87, 88, 89, 90, 91, 84, 92, 93, 94, 95, 212, 212, 212, 212, 212, 212, 212, 212, 212, 227, 227, 227, 227, 227, 227, 227, 227, 84, 100, 73, 241, 118, 118, 118, 84, 99, 369, 369, 369, 369, 369, 369, 228, 424, 242, 242, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 297, 84, 99, 425, 298, 426, 427, 241, 299, 84, 84, 241, 129, 129, 129, 139, 139, 139, 241, 300, 430, 241, 625, 241, 243, 246, 246, 246, 246, 246, 246, 246, 246, 246, 139, 139, 139, 84, 84, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 232, 72, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 252, 431, 252, 432, 253, 437, 253, 557, 254, 444, 255, 84, 256, 256, 73, 256, 84, 84, 84, 257, 84, 257, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 139, 139, 139, 139, 139, 139, 139, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 213, 213, 214, 213, 214, 213, 215, 213, 215, 213, 216, 213, 217, 213, 218, 218, 213, 218, 213, 213, 213, 219, 213, 219, 213, 100, 118, 118, 118, 439, 438, 443, 230, 84, 447, 84, 250, 251, 250, 139, 139, 139, 139, 139, 139, 139, 139, 139, 84, 441, 250, 251, 250, 84, 446, 84, 561, 739, 231, 261, 261, 261, 182, 182, 182, 182, 182, 182, 182, 262, 263, 262, 84, 84, 127, 442, 128, 128, 129, 84, 271, 271, 271, 262, 263, 262, 130, 131, 130, 269, 445, 270, 550, 270, 448, 547, 271, 271, 271, 84, 130, 131, 130, 84, 84, 84, 272, 269, 272, 470, 470, 470, 470, 470, 470, 119, 120, 121, 122, 84, 272, 84, 272, 123, 471, 471, 471, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 100, 564, 84, 264, 265, 266, 267, 230, 261, 261, 261, 268, 212, 212, 212, 212, 212, 212, 212, 84, 134, 135, 136, 137, 273, 274, 275, 276, 138, 261, 261, 261, 277, 231, 271, 271, 271, 271, 271, 271, 273, 274, 275, 276, 84, 568, 566, 552, 277, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 551, 84, 84, 84, 84, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 127, 546, 129, 129, 129, 537, 278, 84, 279, 279, 279, 84, 130, 131, 130, 565, 555, 279, 279, 279, 279, 415, 84, 734, 84, 548, 130, 131, 130, 279, 279, 279, 279, 279, 279, 280, 84, 280, 84, 281, 559, 281, 415, 282, 549, 283, 84, 284, 284, 127, 284, 139, 139, 139, 285, 84, 285, 553, 84, 563, 84, 130, 131, 130, 132, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 130, 131, 130, 84, 554, 658, 84, 132, 118, 118, 118, 118, 118, 118, 118, 84, 134, 135, 136, 137, 731, 287, 556, 287, 138, 288, 84, 288, 560, 289, 562, 290, 84, 291, 291, 127, 291, 330, 330, 330, 292, 558, 292, 84, 84, 712, 84, 331, 332, 331, 339, 339, 339, 339, 339, 339, 339, 339, 339, 84, 567, 331, 332, 331, 84, 140, 141, 142, 143, 456, 456, 456, 656, 144, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 362, 362, 362, 362, 362, 362, 362, 362, 362, 100, 415, 364, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 365, 365, 330, 330, 330, 729, 415, 333, 334, 335, 336, 382, 382, 382, 84, 337, 71, 660, 71, 382, 382, 382, 364, 390, 390, 390, 364, 390, 390, 390, 84, 650, 705, 364, 649, 84, 364, 84, 364, 366, 368, 368, 368, 368, 368, 368, 368, 368, 368, 341, 230, 261, 261, 261, 261, 261, 261, 261, 84, 229, 229, 229, 84, 84, 733, 84, 651, 663, 229, 229, 229, 229, 271, 271, 271, 271, 271, 271, 271, 84, 229, 229, 229, 229, 229, 229, 381, 654, 381, 84, 84, 382, 382, 382, 84, 652, 714, 723, 229, 713, 84, 250, 657, 250, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 709, 250, 84, 250, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 71, 84, 72, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 84, 73, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 383, 384, 385, 386, 569, 569, 569, 84, 387, 261, 261, 261, 129, 129, 129, 129, 129, 129, 129, 262, 263, 262, 389, 84, 389, 711, 84, 390, 390, 390, 84, 662, 84, 262, 263, 262, 730, 262, 706, 262, 261, 261, 261, 261, 261, 261, 261, 261, 261, 84, 84, 262, 84, 262, 449, 449, 449, 707, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 84, 72, 271, 271, 271, 139, 139, 139, 139, 139, 139, 139, 272, 708, 272, 351, 351, 351, 539, 539, 539, 264, 265, 266, 267, 84, 272, 703, 272, 268, 84, 84, 73, 539, 539, 539, 737, 84, 710, 391, 392, 393, 394, 728, 396, 740, 396, 395, 397, 722, 397, 84, 398, 84, 399, 736, 400, 400, 702, 400, 632, 632, 632, 401, 732, 401, 271, 271, 271, 271, 271, 271, 271, 271, 271, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 342, 632, 632, 632, 84, 741, 273, 274, 275, 276, 84, 211, 84, 738, 277, 84, 74, 74, 74, 352, 353, 354, 355, 76, 76, 76, 76, 356, 77, 78, 79, 80, 81, 82, 71, 661, 71, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 84, 742, 743, 357, 357, 357, 84, 84, 655, 84, 653, 744, 357, 357, 357, 357, 84, 84, 84, 646, 341, 645, 626, 211, 357, 357, 357, 357, 357, 357, 576, 404, 84, 404, 84, 405, 84, 405, 84, 406, 84, 407, 206, 408, 408, 84, 408, 412, 412, 412, 409, 413, 409, 279, 279, 279, 412, 412, 412, 412, 84, 84, 279, 279, 279, 279, 414, 415, 412, 412, 412, 412, 412, 412, 279, 279, 279, 279, 279, 279, 84, 533, 532, 525, 414, 524, 84, 84, 415, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 71, 84, 72, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 84, 73, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 84, 85, 85, 85, 456, 456, 456, 456, 456, 456, 456, 207, 207, 207, 207, 207, 207, 207, 463, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 418, 72, 456, 456, 456, 456, 456, 456, 456, 456, 456, 227, 227, 227, 227, 227, 227, 227, 227, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 73, 84, 464, 469, 469, 469, 469, 469, 469, 469, 469, 469, 84, 84, 84, 411, 410, 403, 86, 87, 88, 89, 90, 91, 402, 92, 93, 94, 95, 211, 181, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 100, 85, 85, 85, 329, 324, 323, 100, 322, 321, 320, 317, 71, 314, 313, 312, 311, 310, 309, 465, 382, 382, 382, 382, 382, 382, 382, 308, 466, 466, 307, 306, 127, 231, 330, 330, 330, 305, 304, 303, 302, 301, 296, 419, 331, 332, 331, 295, 294, 293, 465, 198, 286, 259, 465, 258, 249, 220, 331, 332, 331, 465, 68, 190, 465, 150, 465, 467, 390, 390, 390, 390, 390, 390, 390, 147, 84, 382, 382, 382, 111, 390, 390, 390, 96, 69, 68, 745, 86, 87, 88, 89, 90, 91, 745, 92, 93, 94, 95, 745, 745, 745, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 100, 745, 745, 333, 334, 335, 336, 100, 745, 745, 745, 337, 382, 382, 382, 382, 382, 382, 382, 382, 382, 207, 207, 207, 207, 207, 207, 207, 745, 745, 745, 745, 745, 231, 478, 478, 478, 478, 478, 478, 478, 478, 478, 745, 745, 745, 383, 384, 385, 386, 391, 392, 393, 394, 387, 745, 745, 745, 395, 745, 745, 745, 745, 745, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 100, 229, 229, 229, 382, 382, 382, 230, 745, 745, 229, 229, 229, 229, 250, 745, 250, 745, 745, 745, 745, 745, 229, 229, 229, 229, 229, 229, 250, 270, 250, 270, 745, 231, 449, 449, 449, 745, 745, 745, 229, 745, 745, 745, 450, 745, 450, 745, 367, 367, 367, 367, 367, 367, 367, 745, 745, 745, 450, 745, 450, 506, 506, 506, 506, 506, 506, 506, 506, 506, 745, 518, 745, 518, 745, 519, 84, 519, 745, 520, 745, 521, 745, 522, 522, 745, 522, 745, 745, 745, 523, 745, 523, 383, 384, 385, 386, 745, 745, 745, 745, 387, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 100, 745, 745, 451, 452, 453, 454, 230, 745, 745, 745, 455, 745, 515, 515, 515, 371, 371, 371, 745, 745, 745, 515, 515, 515, 515, 261, 261, 261, 261, 261, 261, 261, 231, 515, 515, 515, 515, 515, 515, 745, 745, 745, 118, 118, 118, 745, 745, 745, 745, 745, 745, 229, 250, 251, 250, 390, 390, 390, 390, 390, 390, 390, 390, 390, 745, 745, 250, 251, 250, 745, 745, 745, 745, 390, 390, 390, 271, 271, 271, 271, 271, 271, 271, 262, 745, 262, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 745, 262, 745, 262, 745, 232, 232, 232, 372, 373, 374, 375, 234, 234, 234, 234, 376, 235, 236, 237, 238, 239, 240, 100, 745, 745, 745, 745, 745, 745, 100, 745, 745, 745, 745, 119, 120, 121, 122, 377, 377, 377, 745, 123, 745, 745, 745, 745, 377, 377, 377, 377, 745, 745, 745, 745, 231, 745, 745, 745, 377, 377, 377, 377, 377, 377, 391, 392, 393, 394, 745, 526, 745, 526, 395, 527, 745, 527, 243, 528, 745, 529, 745, 530, 530, 745, 530, 745, 745, 745, 531, 745, 531, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 745, 745, 745, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 213, 213, 457, 213, 457, 213, 458, 213, 458, 213, 459, 213, 460, 213, 461, 461, 213, 461, 213, 213, 213, 462, 213, 462, 213, 71, 745, 71, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 341, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 745, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 71, 745, 72, 569, 569, 569, 569, 569, 569, 569, 745, 745, 745, 412, 412, 412, 472, 472, 472, 745, 745, 745, 412, 412, 412, 412, 745, 536, 745, 745, 745, 745, 745, 73, 412, 412, 412, 412, 412, 412, 412, 412, 412, 745, 745, 745, 745, 745, 536, 412, 412, 412, 412, 538, 415, 538, 745, 745, 539, 539, 539, 412, 412, 412, 412, 412, 412, 745, 540, 745, 540, 745, 745, 745, 745, 415, 745, 745, 745, 745, 745, 745, 540, 745, 540, 569, 569, 569, 569, 569, 569, 569, 569, 569, 456, 456, 456, 456, 456, 456, 456, 745, 74, 74, 74, 473, 474, 475, 476, 76, 76, 76, 76, 477, 77, 78, 79, 80, 81, 82, 71, 745, 72, 227, 227, 227, 227, 227, 227, 227, 227, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 745, 745, 745, 745, 745, 577, 541, 542, 543, 544, 745, 745, 73, 745, 545, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 207, 207, 207, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 745, 745, 745, 745, 745, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 478, 478, 478, 478, 478, 478, 478, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 74, 74, 479, 74, 479, 74, 480, 74, 480, 74, 481, 74, 482, 74, 483, 483, 74, 483, 74, 74, 74, 484, 74, 484, 74, 74, 485, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 745, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 74, 745, 74, 745, 745, 745, 74, 745, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 745, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 74, 745, 74, 745, 745, 745, 74, 745, 74, 486, 71, 745, 71, 207, 207, 207, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 487, 487, 487, 745, 745, 745, 745, 745, 745, 487, 487, 487, 487, 745, 745, 745, 745, 341, 203, 203, 203, 487, 487, 487, 487, 487, 487, 203, 203, 203, 203, 745, 207, 207, 207, 207, 207, 207, 207, 203, 203, 203, 203, 203, 203, 589, 589, 589, 589, 589, 589, 589, 589, 589, 745, 745, 745, 203, 207, 207, 207, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 207, 207, 207, 207, 598, 598, 598, 598, 598, 598, 598, 598, 598, 745, 745, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 100, 127, 745, 129, 129, 129, 745, 100, 745, 745, 745, 745, 745, 130, 131, 130, 478, 478, 478, 745, 207, 207, 207, 207, 207, 207, 207, 130, 131, 130, 745, 745, 127, 231, 139, 139, 139, 207, 207, 207, 207, 207, 207, 207, 130, 131, 130, 132, 745, 745, 539, 539, 539, 745, 449, 449, 449, 745, 130, 131, 130, 745, 745, 745, 450, 132, 450, 745, 745, 745, 745, 127, 745, 330, 330, 330, 745, 745, 450, 745, 450, 745, 745, 331, 332, 331, 745, 745, 745, 745, 745, 745, 134, 135, 136, 137, 84, 331, 332, 331, 138, 745, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 100, 745, 745, 140, 141, 142, 143, 100, 745, 745, 745, 144, 745, 745, 745, 745, 490, 490, 490, 541, 542, 543, 544, 451, 452, 453, 454, 545, 745, 745, 745, 455, 745, 231, 207, 207, 207, 207, 207, 207, 207, 745, 333, 334, 335, 336, 745, 745, 745, 745, 337, 207, 207, 207, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 745, 745, 745, 632, 632, 632, 207, 207, 207, 207, 207, 207, 207, 478, 478, 478, 745, 207, 207, 207, 207, 207, 207, 207, 367, 367, 367, 367, 367, 367, 367, 232, 232, 232, 491, 492, 493, 494, 234, 234, 234, 234, 495, 235, 236, 237, 238, 239, 240, 100, 745, 745, 745, 745, 745, 745, 100, 618, 618, 618, 618, 618, 618, 618, 745, 496, 496, 496, 745, 745, 745, 745, 745, 745, 496, 496, 496, 496, 745, 745, 745, 745, 231, 745, 745, 745, 496, 496, 496, 496, 496, 496, 634, 635, 636, 637, 599, 599, 599, 745, 638, 745, 745, 745, 366, 599, 599, 599, 599, 745, 367, 367, 367, 367, 367, 367, 367, 599, 599, 599, 599, 599, 599, 606, 606, 606, 606, 606, 606, 606, 606, 606, 745, 745, 745, 203, 367, 367, 367, 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, 745, 745, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 229, 229, 229, 745, 745, 745, 745, 745, 745, 229, 229, 229, 229, 745, 367, 367, 367, 367, 367, 367, 367, 229, 229, 229, 229, 229, 229, 618, 618, 618, 618, 618, 618, 618, 618, 618, 506, 506, 506, 229, 367, 367, 367, 367, 367, 367, 367, 745, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 230, 745, 745, 745, 745, 745, 230, 745, 745, 500, 500, 500, 745, 745, 745, 229, 229, 229, 229, 229, 229, 229, 745, 745, 229, 229, 229, 229, 745, 745, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 745, 619, 745, 619, 745, 620, 229, 620, 745, 621, 745, 622, 745, 623, 623, 745, 623, 745, 745, 745, 624, 745, 624, 367, 367, 367, 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, 367, 367, 367, 627, 627, 627, 627, 627, 627, 627, 627, 627, 627, 382, 382, 382, 382, 382, 382, 382, 501, 502, 503, 504, 745, 745, 745, 745, 505, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 506, 506, 506, 506, 506, 506, 506, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 232, 232, 507, 232, 507, 232, 508, 232, 508, 232, 509, 232, 510, 232, 511, 511, 232, 511, 232, 232, 232, 512, 232, 512, 232, 232, 513, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 514, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, 213, 213, 570, 213, 570, 213, 571, 213, 571, 213, 572, 213, 573, 213, 574, 574, 213, 574, 213, 213, 213, 575, 213, 575, 213, 71, 745, 71, 367, 367, 367, 367, 627, 627, 627, 627, 627, 627, 627, 627, 627, 367, 367, 367, 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, 745, 745, 745, 745, 341, 506, 506, 506, 506, 506, 506, 506, 745, 745, 745, 745, 745, 745, 367, 367, 367, 367, 367, 367, 367, 506, 506, 506, 745, 367, 367, 367, 367, 367, 367, 367, 628, 628, 628, 745, 745, 745, 745, 745, 745, 628, 628, 628, 628, 390, 390, 390, 390, 390, 390, 390, 745, 628, 628, 628, 628, 628, 628, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 71, 745, 71, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 745, 745, 745, 579, 579, 579, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 745, 745, 745, 745, 341, 629, 629, 629, 629, 629, 629, 629, 629, 629, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 342, 342, 342, 580, 581, 582, 583, 344, 344, 344, 344, 584, 345, 346, 347, 348, 349, 350, 71, 745, 71, 539, 539, 539, 539, 539, 539, 539, 745, 745, 468, 468, 468, 745, 585, 585, 585, 671, 671, 671, 671, 671, 671, 585, 585, 585, 585, 745, 745, 745, 745, 341, 745, 745, 745, 585, 585, 585, 585, 585, 585, 539, 539, 539, 539, 539, 539, 539, 539, 539, 745, 745, 745, 467, 745, 745, 261, 261, 261, 569, 569, 569, 569, 569, 569, 569, 262, 263, 262, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 745, 262, 263, 262, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 468, 468, 468, 468, 468, 468, 468, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 203, 203, 203, 745, 745, 745, 745, 745, 745, 203, 203, 203, 203, 367, 367, 367, 367, 367, 367, 367, 745, 203, 203, 203, 203, 203, 203, 264, 265, 266, 267, 745, 745, 745, 745, 268, 606, 606, 606, 203, 367, 367, 367, 367, 367, 367, 367, 745, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 71, 745, 72, 271, 271, 271, 367, 367, 367, 367, 367, 367, 367, 272, 745, 272, 664, 664, 664, 664, 664, 664, 664, 664, 664, 664, 745, 272, 745, 272, 631, 745, 631, 73, 745, 632, 632, 632, 745, 539, 539, 539, 745, 745, 745, 633, 745, 633, 745, 540, 745, 540, 745, 745, 639, 745, 639, 745, 640, 633, 640, 633, 641, 540, 642, 540, 643, 643, 745, 643, 85, 85, 85, 644, 745, 644, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 745, 745, 745, 745, 647, 745, 273, 274, 275, 276, 745, 745, 745, 745, 277, 745, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 745, 72, 745, 634, 635, 636, 637, 541, 542, 543, 544, 638, 745, 745, 745, 545, 207, 683, 683, 683, 683, 683, 683, 683, 683, 683, 745, 745, 745, 745, 745, 745, 73, 745, 745, 745, 86, 87, 88, 89, 90, 91, 745, 92, 93, 94, 95, 367, 367, 367, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 745, 745, 745, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 589, 589, 589, 589, 589, 589, 589, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 74, 74, 590, 74, 590, 74, 591, 74, 591, 74, 592, 74, 593, 74, 594, 594, 74, 594, 74, 74, 74, 595, 74, 595, 74, 74, 596, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 745, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 74, 745, 74, 745, 745, 745, 74, 745, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 745, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 745, 74, 74, 745, 74, 745, 745, 745, 74, 745, 74, 597, 71, 745, 72, 85, 85, 85, 468, 468, 468, 468, 468, 468, 468, 745, 745, 745, 472, 472, 472, 671, 671, 671, 671, 671, 671, 671, 671, 671, 648, 745, 745, 745, 745, 73, 449, 449, 449, 632, 632, 632, 632, 632, 632, 632, 450, 745, 450, 745, 745, 127, 745, 330, 330, 330, 745, 745, 745, 745, 450, 84, 450, 331, 332, 331, 539, 539, 539, 539, 539, 539, 539, 589, 589, 589, 745, 331, 332, 331, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 745, 745, 86, 87, 88, 89, 90, 91, 745, 92, 93, 94, 95, 745, 74, 74, 74, 473, 474, 475, 476, 76, 76, 76, 76, 477, 77, 78, 79, 80, 81, 82, 100, 745, 745, 451, 452, 453, 454, 100, 745, 745, 745, 455, 745, 745, 745, 745, 600, 600, 600, 745, 333, 334, 335, 336, 745, 745, 745, 745, 337, 745, 745, 745, 745, 231, 589, 589, 589, 589, 589, 589, 589, 632, 632, 632, 632, 632, 632, 632, 632, 632, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 589, 589, 589, 745, 745, 745, 745, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 367, 367, 367, 367, 367, 367, 367, 745, 745, 745, 745, 745, 745, 684, 684, 684, 684, 684, 684, 684, 684, 684, 745, 745, 745, 232, 232, 232, 601, 602, 603, 604, 234, 234, 234, 234, 605, 235, 236, 237, 238, 239, 240, 100, 204, 204, 204, 745, 745, 745, 100, 745, 745, 204, 204, 204, 204, 715, 715, 715, 715, 715, 715, 715, 745, 204, 204, 204, 204, 204, 204, 745, 745, 745, 745, 745, 231, 367, 367, 367, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 367, 367, 367, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 745, 745, 745, 745, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 606, 606, 606, 606, 606, 606, 606, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 232, 232, 607, 232, 607, 232, 608, 232, 608, 232, 609, 232, 610, 232, 611, 611, 232, 611, 232, 232, 232, 612, 232, 612, 232, 232, 613, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 614, 100, 745, 745, 745, 606, 606, 606, 100, 367, 367, 367, 367, 367, 367, 367, 745, 615, 615, 615, 745, 745, 745, 745, 745, 745, 615, 615, 615, 615, 745, 745, 745, 745, 231, 745, 745, 745, 615, 615, 615, 615, 615, 615, 367, 367, 367, 367, 693, 693, 693, 693, 693, 693, 693, 693, 693, 367, 367, 367, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 745, 745, 745, 745, 745, 745, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 230, 745, 745, 745, 745, 745, 230, 745, 745, 500, 500, 500, 745, 745, 745, 229, 229, 229, 229, 229, 229, 229, 745, 745, 229, 229, 229, 229, 745, 745, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 367, 367, 367, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 367, 367, 367, 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, 367, 367, 367, 367, 695, 695, 695, 695, 695, 695, 695, 695, 695, 367, 367, 367, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 745, 745, 745, 745, 501, 502, 503, 504, 745, 745, 745, 745, 505, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 71, 745, 71, 618, 618, 618, 745, 367, 367, 367, 367, 367, 367, 367, 745, 745, 665, 665, 665, 745, 745, 618, 618, 618, 618, 618, 618, 618, 745, 745, 745, 745, 745, 341, 367, 367, 367, 367, 367, 367, 367, 618, 618, 618, 745, 367, 367, 367, 367, 367, 367, 367, 241, 241, 241, 382, 382, 382, 745, 745, 745, 241, 241, 241, 241, 250, 745, 250, 745, 745, 390, 390, 390, 241, 241, 241, 241, 241, 241, 250, 262, 250, 262, 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, 745, 262, 745, 262, 745, 745, 745, 745, 745, 342, 342, 342, 666, 667, 668, 669, 344, 344, 344, 344, 670, 345, 346, 347, 348, 349, 350, 71, 696, 71, 696, 745, 697, 745, 697, 745, 698, 745, 699, 745, 700, 700, 745, 700, 745, 745, 745, 701, 745, 701, 745, 383, 384, 385, 386, 745, 745, 745, 745, 387, 341, 745, 745, 745, 745, 745, 391, 392, 393, 394, 745, 745, 745, 745, 395, 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, 745, 745, 745, 745, 745, 745, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 671, 671, 671, 671, 671, 671, 671, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 342, 342, 672, 342, 672, 342, 673, 342, 673, 342, 674, 342, 675, 342, 676, 676, 342, 676, 342, 342, 342, 677, 342, 677, 342, 342, 678, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 745, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 342, 745, 342, 745, 745, 745, 342, 745, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 745, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 745, 342, 342, 745, 342, 745, 745, 745, 342, 745, 342, 679, 71, 745, 71, 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, 745, 745, 745, 680, 680, 680, 745, 745, 745, 745, 745, 745, 680, 680, 680, 680, 745, 745, 745, 745, 341, 745, 745, 745, 680, 680, 680, 680, 680, 680, 704, 704, 704, 704, 704, 704, 704, 704, 704, 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, 203, 203, 203, 745, 745, 745, 745, 745, 745, 203, 203, 203, 203, 745, 468, 468, 468, 468, 468, 468, 468, 203, 203, 203, 203, 203, 203, 715, 715, 715, 715, 715, 715, 715, 715, 715, 745, 745, 745, 745, 342, 342, 342, 342, 342, 343, 344, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 71, 745, 72, 632, 632, 632, 745, 745, 745, 468, 468, 468, 745, 633, 745, 633, 671, 671, 671, 671, 671, 671, 745, 745, 745, 745, 745, 633, 745, 633, 468, 468, 468, 73, 449, 449, 449, 671, 671, 671, 671, 671, 671, 745, 450, 745, 450, 671, 671, 671, 745, 468, 468, 468, 468, 468, 468, 468, 450, 84, 450, 716, 745, 716, 745, 717, 745, 717, 745, 718, 745, 719, 745, 720, 720, 745, 720, 745, 745, 745, 721, 745, 721, 468, 468, 468, 468, 468, 468, 468, 745, 745, 634, 635, 636, 637, 745, 745, 745, 745, 638, 745, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 745, 72, 451, 452, 453, 454, 745, 745, 745, 745, 455, 468, 468, 468, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 745, 745, 745, 725, 725, 725, 745, 745, 73, 665, 665, 665, 725, 725, 725, 725, 745, 745, 203, 203, 203, 203, 745, 745, 725, 725, 725, 725, 725, 725, 203, 203, 203, 203, 203, 203, 745, 745, 745, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 71, 745, 72, 666, 667, 668, 669, 745, 745, 745, 745, 670, 745, 745, 745, 745, 472, 472, 472, 468, 468, 468, 468, 724, 724, 724, 724, 724, 724, 724, 724, 724, 745, 73, 671, 671, 671, 671, 671, 671, 671, 745, 745, 745, 745, 745, 745, 468, 468, 468, 468, 468, 468, 468, 671, 671, 671, 745, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 229, 229, 229, 745, 745, 745, 367, 367, 367, 229, 229, 229, 229, 684, 684, 684, 684, 684, 684, 745, 745, 229, 229, 229, 229, 229, 229, 745, 745, 745, 74, 74, 74, 473, 474, 475, 476, 76, 76, 76, 76, 477, 77, 78, 79, 80, 81, 82, 100, 367, 367, 367, 745, 745, 745, 100, 684, 684, 684, 684, 684, 684, 367, 367, 367, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 745, 745, 745, 745, 745, 745, 231, 367, 367, 367, 367, 726, 726, 726, 726, 726, 726, 726, 726, 726, 367, 367, 367, 745, 745, 745, 745, 684, 684, 684, 684, 684, 684, 684, 684, 684, 745, 367, 367, 367, 367, 367, 367, 367, 684, 684, 684, 684, 684, 684, 684, 745, 745, 745, 745, 745, 745, 367, 367, 367, 367, 367, 367, 367, 684, 684, 684, 745, 367, 367, 367, 367, 367, 367, 367, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 100, 364, 364, 364, 745, 745, 745, 100, 745, 745, 364, 364, 364, 364, 745, 745, 745, 745, 745, 230, 745, 745, 364, 364, 364, 364, 364, 364, 229, 229, 229, 745, 745, 231, 745, 745, 745, 229, 229, 229, 229, 632, 632, 632, 632, 632, 632, 632, 745, 229, 229, 229, 229, 229, 229, 727, 727, 727, 727, 727, 727, 727, 727, 727, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 684, 684, 684, 684, 684, 684, 684, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 232, 232, 685, 232, 685, 232, 686, 232, 686, 232, 687, 232, 688, 232, 689, 689, 232, 689, 232, 232, 232, 690, 232, 690, 232, 232, 691, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 745, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 745, 232, 232, 745, 232, 745, 745, 745, 232, 745, 232, 692, 100, 600, 600, 600, 745, 745, 745, 100, 745, 745, 229, 229, 229, 229, 745, 745, 600, 600, 600, 745, 745, 745, 229, 229, 229, 229, 229, 229, 745, 745, 745, 745, 745, 231, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 727, 727, 727, 727, 727, 727, 727, 727, 727, 727, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 745, 539, 539, 539, 745, 745, 745, 745, 745, 745, 745, 540, 745, 540, 745, 745, 601, 602, 603, 604, 745, 745, 745, 745, 605, 540, 745, 540, 232, 232, 232, 601, 602, 603, 604, 234, 234, 234, 234, 605, 235, 236, 237, 238, 239, 240, 100, 745, 745, 745, 715, 715, 715, 100, 468, 468, 468, 468, 468, 468, 468, 745, 694, 694, 694, 745, 745, 745, 745, 745, 745, 694, 694, 694, 694, 745, 745, 745, 745, 231, 745, 745, 745, 694, 694, 694, 694, 694, 694, 745, 541, 542, 543, 544, 203, 203, 203, 745, 545, 745, 745, 745, 745, 203, 203, 203, 203, 745, 745, 745, 745, 745, 745, 745, 745, 203, 203, 203, 203, 203, 203, 468, 468, 468, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 468, 468, 468, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 745, 232, 232, 232, 232, 232, 233, 234, 234, 234, 234, 234, 234, 235, 236, 237, 238, 239, 240, 230, 745, 745, 465, 465, 465, 745, 745, 745, 500, 500, 500, 465, 465, 465, 465, 745, 745, 229, 229, 229, 229, 745, 745, 465, 465, 465, 465, 465, 465, 229, 229, 229, 229, 229, 229, 468, 468, 468, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 468, 468, 468, 468, 735, 735, 735, 735, 735, 735, 735, 735, 735, 468, 468, 468, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 745, 745, 745, 745, 745, 745, 468, 468, 468, 468, 468, 468, 468, 745, 745, 745, 501, 502, 503, 504, 745, 745, 745, 745, 505, 71, 745, 72, 715, 715, 715, 745, 468, 468, 468, 468, 468, 468, 468, 745, 745, 229, 229, 229, 745, 745, 745, 745, 745, 745, 229, 229, 229, 229, 745, 745, 745, 745, 73, 665, 665, 665, 229, 229, 229, 229, 229, 229, 203, 203, 203, 203, 745, 745, 745, 745, 632, 632, 632, 745, 203, 203, 203, 203, 203, 203, 633, 745, 633, 745, 745, 745, 745, 745, 203, 203, 203, 745, 745, 745, 633, 745, 633, 203, 203, 203, 203, 745, 745, 745, 745, 745, 745, 745, 745, 203, 203, 203, 203, 203, 203, 745, 745, 745, 745, 745, 745, 74, 74, 74, 74, 74, 75, 76, 76, 76, 76, 76, 76, 77, 78, 79, 80, 81, 82, 745, 745, 745, 666, 667, 668, 669, 745, 745, 745, 745, 670, 745, 745, 745, 745, 745, 745, 745, 745, 634, 635, 636, 637, 745, 745, 745, 745, 638, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 83, 745, 83, 83, 83, 83, 83, 83, 83, 83, 83, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 180, 180, 745, 180, 180, 181, 181, 181, 181, 181, 181, 183, 183, 183, 183, 183, 183, 194, 194, 194, 196, 196, 196, 196, 196, 196, 199, 745, 199, 745, 199, 199, 199, 199, 199, 199, 199, 200, 745, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 83, 745, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 745, 84, 84, 211, 211, 211, 211, 211, 211, 213, 213, 213, 213, 213, 213, 224, 224, 224, 226, 226, 226, 226, 226, 226, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 260, 745, 260, 260, 260, 260, 260, 260, 260, 260, 260, 181, 181, 181, 181, 181, 181, 339, 339, 339, 339, 339, 339, 180, 180, 180, 180, 180, 180, 340, 340, 340, 340, 340, 340, 340, 340, 340, 199, 745, 199, 745, 199, 199, 199, 199, 199, 199, 199, 200, 745, 200, 745, 745, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 211, 211, 211, 211, 211, 211, 362, 362, 362, 362, 362, 362, 84, 84, 84, 84, 84, 84, 363, 363, 363, 363, 363, 363, 363, 363, 363, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 260, 745, 260, 260, 260, 260, 260, 260, 260, 260, 260, 211, 211, 211, 211, 211, 211, 213, 213, 213, 213, 213, 213, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 211, 211, 211, 211, 211, 211, 213, 213, 213, 213, 213, 213, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 211, 211, 211, 211, 211, 211, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 5, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745 } ; static yyconst flex_int16_t yy_chk[8893] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 12, 12, 12, 14, 19, 36, 23, 21, 3, 4, 10, 23, 10, 28, 28, 19, 21, 21, 23, 14, 30, 30, 36, 37, 36, 45, 38, 38, 48, 47, 45, 67, 795, 39, 38, 42, 67, 40, 39, 37, 38, 48, 22, 10, 22, 22, 22, 39, 40, 42, 40, 25, 47, 25, 25, 25, 41, 44, 49, 40, 52, 50, 43, 25, 25, 25, 25, 41, 43, 50, 41, 44, 49, 315, 169, 43, 167, 25, 25, 25, 35, 35, 35, 167, 25, 169, 315, 12, 12, 12, 12, 12, 12, 201, 12, 12, 12, 12, 201, 52, 35, 57, 57, 57, 57, 57, 57, 57, 82, 82, 82, 303, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15, 46, 303, 22, 22, 22, 22, 15, 784, 46, 46, 22, 25, 25, 25, 25, 110, 110, 110, 46, 25, 317, 46, 58, 58, 58, 58, 58, 58, 58, 58, 58, 176, 15, 176, 175, 317, 35, 35, 35, 35, 35, 35, 175, 35, 35, 35, 35, 61, 61, 61, 61, 189, 189, 189, 61, 62, 62, 62, 62, 62, 64, 64, 64, 64, 64, 64, 64, 64, 80, 80, 80, 80, 80, 80, 562, 61, 562, 84, 84, 84, 198, 198, 198, 64, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 219, 219, 219, 308, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 24, 308, 24, 24, 24, 88, 88, 88, 88, 88, 88, 88, 24, 24, 24, 24, 300, 24, 73, 307, 73, 228, 228, 228, 300, 73, 24, 24, 24, 92, 92, 92, 92, 24, 73, 73, 92, 240, 240, 240, 307, 85, 85, 85, 24, 84, 84, 84, 84, 84, 84, 73, 84, 84, 84, 84, 73, 92, 302, 299, 73, 93, 93, 93, 93, 93, 302, 73, 299, 312, 73, 760, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 108, 108, 108, 108, 108, 108, 321, 312, 24, 24, 24, 24, 257, 257, 257, 321, 24, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 70, 314, 70, 85, 85, 85, 85, 85, 85, 314, 85, 85, 85, 85, 89, 89, 89, 89, 89, 89, 89, 89, 89, 95, 95, 95, 95, 95, 95, 95, 95, 749, 101, 70, 101, 259, 259, 259, 744, 101, 238, 238, 238, 238, 238, 238, 95, 304, 101, 101, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 151, 304, 101, 305, 151, 306, 306, 101, 151, 305, 306, 101, 285, 285, 285, 292, 292, 292, 101, 151, 309, 101, 504, 101, 101, 106, 106, 106, 106, 106, 106, 106, 106, 106, 294, 294, 294, 309, 743, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 74, 504, 74, 119, 119, 119, 119, 119, 119, 119, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 310, 121, 311, 121, 318, 121, 435, 121, 325, 121, 310, 121, 121, 74, 121, 435, 325, 318, 121, 311, 121, 134, 134, 134, 134, 134, 134, 134, 135, 135, 135, 135, 135, 135, 135, 135, 135, 140, 140, 140, 140, 140, 140, 140, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 99, 118, 118, 118, 320, 319, 324, 99, 319, 328, 320, 118, 118, 118, 141, 141, 141, 141, 141, 141, 141, 141, 141, 324, 322, 118, 118, 118, 322, 327, 328, 440, 737, 99, 127, 127, 127, 190, 190, 190, 190, 190, 190, 190, 127, 127, 127, 327, 440, 128, 323, 128, 128, 128, 323, 270, 270, 270, 127, 127, 127, 128, 128, 128, 128, 326, 131, 423, 131, 329, 419, 131, 131, 131, 419, 128, 128, 128, 326, 423, 329, 131, 128, 131, 348, 348, 348, 348, 348, 348, 118, 118, 118, 118, 734, 131, 733, 131, 118, 350, 350, 350, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 102, 443, 732, 127, 127, 127, 127, 102, 401, 401, 401, 127, 220, 220, 220, 220, 220, 220, 220, 443, 128, 128, 128, 128, 270, 270, 270, 270, 128, 403, 403, 403, 270, 102, 409, 409, 409, 411, 411, 411, 131, 131, 131, 131, 731, 448, 445, 427, 131, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 426, 427, 445, 448, 426, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 129, 418, 129, 129, 129, 414, 133, 729, 133, 133, 133, 418, 129, 129, 129, 444, 432, 133, 133, 133, 133, 414, 432, 714, 444, 420, 129, 129, 129, 133, 133, 133, 133, 133, 133, 136, 420, 136, 712, 136, 438, 136, 414, 136, 421, 136, 438, 136, 136, 139, 136, 139, 139, 139, 136, 421, 136, 428, 710, 442, 428, 139, 139, 139, 139, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 139, 139, 139, 442, 429, 561, 561, 139, 258, 258, 258, 258, 258, 258, 258, 429, 129, 129, 129, 129, 709, 142, 433, 142, 129, 142, 433, 142, 439, 142, 441, 142, 439, 142, 142, 182, 142, 182, 182, 182, 142, 437, 142, 441, 661, 661, 437, 182, 182, 182, 192, 192, 192, 192, 192, 192, 192, 192, 192, 558, 447, 182, 182, 182, 447, 139, 139, 139, 139, 462, 462, 462, 558, 139, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 222, 222, 222, 222, 222, 222, 222, 222, 222, 231, 537, 231, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 231, 231, 464, 464, 464, 707, 537, 182, 182, 182, 182, 523, 523, 523, 563, 182, 203, 563, 203, 525, 525, 525, 231, 531, 531, 531, 231, 533, 533, 533, 548, 549, 647, 231, 548, 549, 231, 647, 231, 231, 236, 236, 236, 236, 236, 236, 236, 236, 236, 203, 244, 264, 264, 264, 264, 264, 264, 264, 552, 244, 244, 244, 705, 567, 713, 713, 552, 567, 244, 244, 244, 244, 273, 273, 273, 273, 273, 273, 273, 555, 244, 244, 244, 244, 244, 244, 251, 555, 251, 553, 663, 251, 251, 251, 559, 553, 663, 670, 244, 662, 651, 251, 559, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 651, 251, 660, 251, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 204, 659, 204, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 658, 204, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 251, 251, 251, 251, 575, 575, 575, 657, 251, 261, 261, 261, 286, 286, 286, 286, 286, 286, 286, 261, 261, 261, 263, 566, 263, 656, 655, 263, 263, 263, 648, 566, 708, 261, 261, 261, 708, 263, 648, 263, 265, 265, 265, 265, 265, 265, 265, 265, 265, 649, 654, 263, 653, 263, 577, 577, 577, 649, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, 650, 205, 271, 271, 271, 293, 293, 293, 293, 293, 293, 293, 271, 650, 271, 205, 205, 205, 644, 644, 644, 261, 261, 261, 261, 652, 271, 638, 271, 261, 730, 706, 205, 646, 646, 646, 730, 738, 652, 263, 263, 263, 263, 706, 266, 738, 266, 263, 266, 669, 266, 728, 266, 711, 266, 728, 266, 266, 637, 266, 701, 701, 701, 266, 711, 266, 274, 274, 274, 274, 274, 274, 274, 274, 274, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 669, 703, 703, 703, 736, 739, 271, 271, 271, 271, 739, 573, 568, 736, 271, 565, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 206, 564, 206, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 560, 740, 741, 206, 206, 206, 740, 741, 557, 556, 554, 742, 206, 206, 206, 206, 742, 551, 550, 545, 206, 544, 505, 460, 206, 206, 206, 206, 206, 206, 454, 275, 450, 275, 446, 275, 436, 275, 434, 275, 431, 275, 206, 275, 275, 430, 275, 278, 278, 278, 275, 279, 275, 279, 279, 279, 278, 278, 278, 278, 425, 424, 279, 279, 279, 279, 279, 279, 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 422, 395, 394, 387, 279, 386, 363, 362, 279, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 361, 207, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 340, 207, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 339, 297, 297, 297, 333, 333, 333, 333, 333, 333, 333, 358, 358, 358, 358, 358, 358, 358, 336, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 297, 208, 334, 334, 334, 334, 334, 334, 334, 334, 334, 337, 337, 337, 337, 337, 337, 337, 337, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 208, 331, 337, 346, 346, 346, 346, 346, 346, 346, 346, 346, 316, 313, 301, 277, 276, 268, 297, 297, 297, 297, 297, 297, 267, 297, 297, 297, 297, 217, 187, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 229, 298, 298, 298, 177, 174, 173, 229, 172, 171, 170, 168, 341, 165, 164, 163, 162, 161, 160, 341, 383, 383, 383, 383, 383, 383, 383, 159, 341, 341, 158, 157, 330, 229, 330, 330, 330, 156, 155, 154, 153, 152, 149, 298, 330, 330, 330, 145, 144, 143, 341, 138, 137, 123, 341, 122, 117, 91, 330, 330, 330, 341, 68, 60, 341, 34, 341, 341, 391, 391, 391, 391, 391, 391, 391, 29, 330, 381, 381, 381, 18, 389, 389, 389, 13, 9, 7, 5, 298, 298, 298, 298, 298, 298, 0, 298, 298, 298, 298, 0, 0, 0, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 232, 0, 0, 330, 330, 330, 330, 232, 0, 0, 0, 330, 384, 384, 384, 384, 384, 384, 384, 384, 384, 353, 353, 353, 353, 353, 353, 353, 0, 0, 0, 0, 0, 232, 353, 353, 353, 353, 353, 353, 353, 353, 353, 0, 0, 0, 381, 381, 381, 381, 389, 389, 389, 389, 381, 0, 0, 0, 389, 0, 0, 0, 0, 0, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 241, 367, 367, 367, 382, 382, 382, 241, 0, 0, 367, 367, 367, 367, 382, 0, 382, 0, 0, 0, 0, 0, 367, 367, 367, 367, 367, 367, 382, 332, 382, 332, 0, 241, 332, 332, 332, 0, 0, 0, 367, 0, 0, 0, 332, 0, 332, 0, 373, 373, 373, 373, 373, 373, 373, 0, 0, 0, 332, 0, 332, 373, 373, 373, 373, 373, 373, 373, 373, 373, 0, 385, 0, 385, 0, 385, 332, 385, 0, 385, 0, 385, 0, 385, 385, 0, 385, 0, 0, 0, 385, 0, 385, 382, 382, 382, 382, 0, 0, 0, 0, 382, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 332, 332, 332, 332, 242, 0, 0, 0, 332, 0, 377, 377, 377, 242, 242, 242, 0, 0, 0, 377, 377, 377, 377, 402, 402, 402, 402, 402, 402, 402, 242, 377, 377, 377, 377, 377, 377, 0, 0, 0, 388, 388, 388, 0, 0, 0, 0, 0, 0, 377, 388, 388, 388, 392, 392, 392, 392, 392, 392, 392, 392, 392, 0, 0, 388, 388, 388, 0, 0, 0, 0, 390, 390, 390, 410, 410, 410, 410, 410, 410, 410, 390, 0, 390, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 0, 390, 0, 390, 0, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 243, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 388, 388, 388, 388, 243, 243, 243, 0, 388, 0, 0, 0, 0, 243, 243, 243, 243, 0, 0, 0, 0, 243, 0, 0, 0, 243, 243, 243, 243, 243, 243, 390, 390, 390, 390, 0, 393, 0, 393, 390, 393, 0, 393, 243, 393, 0, 393, 0, 393, 393, 0, 393, 0, 0, 0, 393, 0, 393, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, 399, 399, 399, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 342, 0, 342, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 342, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 407, 407, 407, 407, 407, 407, 407, 407, 407, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 0, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 351, 0, 351, 451, 451, 451, 451, 451, 451, 451, 0, 0, 0, 412, 412, 412, 351, 351, 351, 0, 0, 0, 412, 412, 412, 412, 0, 412, 0, 0, 0, 0, 0, 351, 412, 412, 412, 412, 412, 412, 413, 413, 413, 0, 0, 0, 0, 0, 412, 413, 413, 413, 413, 415, 413, 415, 0, 0, 415, 415, 415, 413, 413, 413, 413, 413, 413, 0, 415, 0, 415, 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, 0, 415, 0, 415, 452, 452, 452, 452, 452, 452, 452, 452, 452, 463, 463, 463, 463, 463, 463, 463, 0, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 352, 0, 352, 455, 455, 455, 455, 455, 455, 455, 455, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 0, 0, 0, 0, 0, 455, 415, 415, 415, 415, 0, 0, 352, 0, 415, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 0, 0, 0, 0, 0, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 0, 0, 355, 0, 355, 0, 355, 0, 355, 0, 355, 0, 355, 0, 355, 355, 0, 355, 0, 0, 0, 355, 0, 355, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 0, 0, 356, 0, 356, 0, 356, 0, 356, 0, 356, 0, 356, 0, 356, 356, 0, 356, 0, 0, 0, 356, 0, 356, 356, 357, 0, 357, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 357, 357, 357, 0, 0, 0, 0, 0, 0, 357, 357, 357, 357, 0, 0, 0, 0, 357, 468, 468, 468, 357, 357, 357, 357, 357, 357, 468, 468, 468, 468, 0, 474, 474, 474, 474, 474, 474, 474, 468, 468, 468, 468, 468, 468, 474, 474, 474, 474, 474, 474, 474, 474, 474, 0, 0, 0, 468, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 0, 0, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 364, 416, 0, 416, 416, 416, 0, 364, 0, 0, 0, 0, 0, 416, 416, 416, 484, 484, 484, 0, 484, 484, 484, 484, 484, 484, 484, 416, 416, 416, 0, 0, 417, 364, 417, 417, 417, 488, 488, 488, 488, 488, 488, 488, 417, 417, 417, 417, 0, 0, 538, 538, 538, 0, 449, 449, 449, 0, 417, 417, 417, 0, 0, 0, 449, 417, 449, 0, 0, 0, 0, 456, 0, 456, 456, 456, 0, 0, 449, 0, 449, 0, 0, 456, 456, 456, 0, 0, 0, 0, 0, 0, 416, 416, 416, 416, 449, 456, 456, 456, 416, 0, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 365, 0, 0, 417, 417, 417, 417, 365, 0, 0, 0, 417, 0, 0, 0, 0, 365, 365, 365, 538, 538, 538, 538, 449, 449, 449, 449, 538, 0, 0, 0, 449, 0, 365, 489, 489, 489, 489, 489, 489, 489, 0, 456, 456, 456, 456, 0, 0, 0, 0, 456, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 485, 485, 485, 485, 485, 485, 485, 0, 0, 0, 631, 631, 631, 485, 485, 485, 485, 485, 485, 485, 486, 486, 486, 0, 486, 486, 486, 486, 486, 486, 486, 497, 497, 497, 497, 497, 497, 497, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 366, 0, 0, 0, 0, 0, 0, 366, 501, 501, 501, 501, 501, 501, 501, 0, 366, 366, 366, 0, 0, 0, 0, 0, 0, 366, 366, 366, 366, 0, 0, 0, 0, 366, 0, 0, 0, 366, 366, 366, 366, 366, 366, 631, 631, 631, 631, 487, 487, 487, 0, 631, 0, 0, 0, 366, 487, 487, 487, 487, 0, 492, 492, 492, 492, 492, 492, 492, 487, 487, 487, 487, 487, 487, 492, 492, 492, 492, 492, 492, 492, 492, 492, 0, 0, 0, 487, 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, 0, 0, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 368, 368, 368, 0, 0, 0, 0, 0, 0, 368, 368, 368, 368, 0, 502, 502, 502, 502, 502, 502, 502, 368, 368, 368, 368, 368, 368, 502, 502, 502, 502, 502, 502, 502, 502, 502, 512, 512, 512, 368, 512, 512, 512, 512, 512, 512, 512, 0, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 0, 0, 0, 0, 0, 500, 0, 0, 371, 371, 371, 0, 0, 0, 500, 500, 500, 371, 371, 371, 371, 0, 0, 500, 500, 500, 500, 0, 0, 371, 371, 371, 371, 371, 371, 500, 500, 500, 500, 500, 500, 0, 503, 0, 503, 0, 503, 371, 503, 0, 503, 0, 503, 0, 503, 503, 0, 503, 0, 0, 0, 503, 0, 503, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 524, 524, 524, 524, 524, 524, 524, 371, 371, 371, 371, 0, 0, 0, 0, 371, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 0, 0, 375, 0, 375, 0, 375, 0, 375, 0, 375, 0, 375, 0, 375, 375, 0, 375, 0, 0, 0, 375, 0, 375, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 0, 0, 376, 0, 376, 0, 376, 0, 376, 0, 376, 0, 376, 0, 376, 376, 0, 376, 0, 0, 0, 376, 0, 376, 376, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 465, 0, 465, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 0, 0, 0, 0, 465, 513, 513, 513, 513, 513, 513, 513, 0, 0, 0, 0, 0, 0, 513, 513, 513, 513, 513, 513, 513, 514, 514, 514, 0, 514, 514, 514, 514, 514, 514, 514, 515, 515, 515, 0, 0, 0, 0, 0, 0, 515, 515, 515, 515, 532, 532, 532, 532, 532, 532, 532, 0, 515, 515, 515, 515, 515, 515, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 0, 466, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 0, 0, 0, 466, 466, 466, 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, 0, 0, 0, 0, 466, 521, 521, 521, 521, 521, 521, 521, 521, 521, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 0, 467, 541, 541, 541, 541, 541, 541, 541, 0, 0, 672, 672, 672, 0, 467, 467, 467, 672, 672, 672, 672, 672, 672, 467, 467, 467, 467, 0, 0, 0, 0, 467, 0, 0, 0, 467, 467, 467, 467, 467, 467, 542, 542, 542, 542, 542, 542, 542, 542, 542, 0, 0, 0, 467, 0, 0, 534, 534, 534, 576, 576, 576, 576, 576, 576, 576, 534, 534, 534, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 0, 534, 534, 534, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 586, 586, 586, 586, 586, 586, 586, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 469, 469, 469, 0, 0, 0, 0, 0, 0, 469, 469, 469, 469, 616, 616, 616, 616, 616, 616, 616, 0, 469, 469, 469, 469, 469, 469, 534, 534, 534, 534, 0, 0, 0, 0, 534, 612, 612, 612, 469, 612, 612, 612, 612, 612, 612, 612, 0, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 472, 0, 472, 535, 535, 535, 617, 617, 617, 617, 617, 617, 617, 535, 0, 535, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 0, 535, 0, 535, 536, 0, 536, 472, 0, 536, 536, 536, 0, 539, 539, 539, 0, 0, 0, 536, 0, 536, 0, 539, 0, 539, 0, 0, 543, 0, 543, 0, 543, 536, 543, 536, 543, 539, 543, 539, 543, 543, 0, 543, 546, 546, 546, 543, 0, 543, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 0, 0, 0, 0, 546, 0, 535, 535, 535, 535, 0, 0, 0, 0, 535, 0, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 473, 0, 473, 0, 536, 536, 536, 536, 539, 539, 539, 539, 536, 0, 0, 0, 539, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 546, 546, 546, 546, 546, 546, 0, 546, 546, 546, 546, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 0, 0, 0, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 0, 0, 476, 0, 476, 0, 476, 0, 476, 0, 476, 0, 476, 0, 476, 476, 0, 476, 0, 0, 0, 476, 0, 476, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 0, 0, 477, 0, 477, 0, 477, 0, 477, 0, 477, 0, 477, 0, 477, 477, 0, 477, 0, 0, 0, 477, 0, 477, 477, 478, 0, 478, 547, 547, 547, 581, 581, 581, 581, 581, 581, 581, 0, 0, 0, 478, 478, 478, 581, 581, 581, 581, 581, 581, 581, 581, 581, 547, 0, 0, 0, 0, 478, 569, 569, 569, 634, 634, 634, 634, 634, 634, 634, 569, 0, 569, 0, 0, 578, 0, 578, 578, 578, 0, 0, 0, 0, 569, 569, 569, 578, 578, 578, 645, 645, 645, 645, 645, 645, 645, 595, 595, 595, 0, 578, 578, 578, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 0, 0, 547, 547, 547, 547, 547, 547, 0, 547, 547, 547, 547, 0, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 490, 0, 0, 569, 569, 569, 569, 490, 0, 0, 0, 569, 0, 0, 0, 0, 490, 490, 490, 0, 578, 578, 578, 578, 0, 0, 0, 0, 578, 0, 0, 0, 0, 490, 596, 596, 596, 596, 596, 596, 596, 635, 635, 635, 635, 635, 635, 635, 635, 635, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 597, 597, 0, 0, 0, 0, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 602, 602, 602, 602, 602, 602, 602, 0, 0, 0, 0, 0, 0, 602, 602, 602, 602, 602, 602, 602, 602, 602, 0, 0, 0, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 491, 599, 599, 599, 0, 0, 0, 491, 0, 0, 599, 599, 599, 599, 666, 666, 666, 666, 666, 666, 666, 0, 599, 599, 599, 599, 599, 599, 0, 0, 0, 0, 0, 491, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 0, 0, 0, 0, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, 0, 0, 494, 0, 494, 0, 494, 0, 494, 0, 494, 0, 494, 0, 494, 494, 0, 494, 0, 0, 0, 494, 0, 494, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 0, 0, 495, 0, 495, 0, 495, 0, 495, 0, 495, 0, 495, 0, 495, 495, 0, 495, 0, 0, 0, 495, 0, 495, 495, 496, 0, 0, 0, 614, 614, 614, 496, 614, 614, 614, 614, 614, 614, 614, 0, 496, 496, 496, 0, 0, 0, 0, 0, 0, 496, 496, 496, 496, 0, 0, 0, 0, 496, 0, 0, 0, 496, 496, 496, 496, 496, 496, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 613, 613, 613, 613, 613, 613, 613, 0, 0, 0, 0, 0, 0, 613, 613, 613, 613, 613, 613, 613, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 506, 0, 0, 0, 0, 0, 618, 0, 0, 506, 506, 506, 0, 0, 0, 618, 618, 618, 506, 506, 506, 506, 0, 0, 618, 618, 618, 618, 0, 0, 506, 506, 506, 506, 506, 506, 618, 618, 618, 618, 618, 618, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 0, 0, 0, 0, 506, 506, 506, 506, 0, 0, 0, 0, 506, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 579, 0, 579, 624, 624, 624, 0, 624, 624, 624, 624, 624, 624, 624, 0, 0, 579, 579, 579, 0, 0, 625, 625, 625, 625, 625, 625, 625, 0, 0, 0, 0, 0, 579, 625, 625, 625, 625, 625, 625, 625, 626, 626, 626, 0, 626, 626, 626, 626, 626, 626, 626, 628, 628, 628, 629, 629, 629, 0, 0, 0, 628, 628, 628, 628, 629, 0, 629, 0, 0, 630, 630, 630, 628, 628, 628, 628, 628, 628, 629, 630, 629, 630, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 0, 630, 0, 630, 0, 0, 0, 0, 0, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 580, 636, 580, 636, 0, 636, 0, 636, 0, 636, 0, 636, 0, 636, 636, 0, 636, 0, 0, 0, 636, 0, 636, 0, 629, 629, 629, 629, 0, 0, 0, 0, 629, 580, 0, 0, 0, 0, 0, 630, 630, 630, 630, 0, 0, 0, 0, 630, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 0, 0, 0, 0, 0, 0, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, 0, 0, 583, 0, 583, 0, 583, 0, 583, 0, 583, 0, 583, 0, 583, 583, 0, 583, 0, 0, 0, 583, 0, 583, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 0, 0, 584, 0, 584, 0, 584, 0, 584, 0, 584, 0, 584, 0, 584, 584, 0, 584, 0, 0, 0, 584, 0, 584, 584, 585, 0, 585, 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 0, 0, 0, 585, 585, 585, 0, 0, 0, 0, 0, 0, 585, 585, 585, 585, 0, 0, 0, 0, 585, 0, 0, 0, 585, 585, 585, 585, 585, 585, 642, 642, 642, 642, 642, 642, 642, 642, 642, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 665, 665, 665, 0, 0, 0, 0, 0, 0, 665, 665, 665, 665, 0, 667, 667, 667, 667, 667, 667, 667, 665, 665, 665, 665, 665, 665, 667, 667, 667, 667, 667, 667, 667, 667, 667, 0, 0, 0, 0, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 589, 0, 589, 632, 632, 632, 0, 0, 0, 673, 673, 673, 0, 632, 0, 632, 673, 673, 673, 673, 673, 673, 0, 0, 0, 0, 0, 632, 0, 632, 676, 676, 676, 589, 664, 664, 664, 676, 676, 676, 676, 676, 676, 0, 664, 0, 664, 677, 677, 677, 0, 677, 677, 677, 677, 677, 677, 677, 664, 664, 664, 668, 0, 668, 0, 668, 0, 668, 0, 668, 0, 668, 0, 668, 668, 0, 668, 0, 0, 0, 668, 0, 668, 681, 681, 681, 681, 681, 681, 681, 0, 0, 632, 632, 632, 632, 0, 0, 0, 0, 632, 0, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590, 0, 590, 664, 664, 664, 664, 0, 0, 0, 0, 664, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 0, 0, 0, 680, 680, 680, 0, 0, 590, 671, 671, 671, 680, 680, 680, 680, 0, 0, 671, 671, 671, 671, 0, 0, 680, 680, 680, 680, 680, 680, 671, 671, 671, 671, 671, 671, 0, 0, 0, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 598, 0, 598, 671, 671, 671, 671, 0, 0, 0, 0, 671, 0, 0, 0, 0, 598, 598, 598, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 0, 598, 678, 678, 678, 678, 678, 678, 678, 0, 0, 0, 0, 0, 0, 678, 678, 678, 678, 678, 678, 678, 679, 679, 679, 0, 679, 679, 679, 679, 679, 679, 679, 682, 682, 682, 682, 682, 682, 682, 684, 684, 684, 0, 0, 0, 685, 685, 685, 684, 684, 684, 684, 685, 685, 685, 685, 685, 685, 0, 0, 684, 684, 684, 684, 684, 684, 0, 0, 0, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 600, 686, 686, 686, 0, 0, 0, 600, 686, 686, 686, 686, 686, 686, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 0, 0, 0, 0, 0, 0, 600, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 689, 689, 689, 0, 0, 0, 0, 689, 689, 689, 689, 689, 689, 690, 690, 690, 0, 690, 690, 690, 690, 690, 690, 690, 691, 691, 691, 691, 691, 691, 691, 0, 0, 0, 0, 0, 0, 691, 691, 691, 691, 691, 691, 691, 692, 692, 692, 0, 692, 692, 692, 692, 692, 692, 692, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 694, 694, 694, 0, 0, 0, 601, 0, 0, 694, 694, 694, 694, 0, 0, 0, 0, 0, 695, 0, 0, 694, 694, 694, 694, 694, 694, 695, 695, 695, 0, 0, 601, 0, 0, 0, 695, 695, 695, 695, 702, 702, 702, 702, 702, 702, 702, 0, 695, 695, 695, 695, 695, 695, 699, 699, 699, 699, 699, 699, 699, 699, 699, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 0, 0, 604, 0, 604, 0, 604, 0, 604, 0, 604, 0, 604, 0, 604, 604, 0, 604, 0, 0, 0, 604, 0, 604, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 0, 0, 605, 0, 605, 0, 605, 0, 605, 0, 605, 0, 605, 0, 605, 605, 0, 605, 0, 0, 0, 605, 0, 605, 605, 606, 693, 693, 693, 0, 0, 0, 606, 0, 0, 693, 693, 693, 693, 0, 0, 606, 606, 606, 0, 0, 0, 693, 693, 693, 693, 693, 693, 0, 0, 0, 0, 0, 606, 696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 0, 704, 704, 704, 0, 0, 0, 0, 0, 0, 0, 704, 0, 704, 0, 0, 693, 693, 693, 693, 0, 0, 0, 0, 693, 704, 0, 704, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 615, 0, 0, 0, 721, 721, 721, 615, 721, 721, 721, 721, 721, 721, 721, 0, 615, 615, 615, 0, 0, 0, 0, 0, 0, 615, 615, 615, 615, 0, 0, 0, 0, 615, 0, 0, 0, 615, 615, 615, 615, 615, 615, 0, 704, 704, 704, 704, 715, 715, 715, 0, 704, 0, 0, 0, 0, 715, 715, 715, 715, 0, 0, 0, 0, 0, 0, 0, 0, 715, 715, 715, 715, 715, 715, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 0, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 627, 0, 0, 725, 725, 725, 0, 0, 0, 627, 627, 627, 725, 725, 725, 725, 0, 0, 627, 627, 627, 627, 0, 0, 725, 725, 725, 725, 725, 725, 627, 627, 627, 627, 627, 627, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 722, 722, 722, 722, 722, 722, 722, 0, 0, 0, 0, 0, 0, 722, 722, 722, 722, 722, 722, 722, 0, 0, 0, 627, 627, 627, 627, 0, 0, 0, 0, 627, 683, 0, 683, 723, 723, 723, 0, 723, 723, 723, 723, 723, 723, 723, 0, 0, 726, 726, 726, 0, 0, 0, 0, 0, 0, 726, 726, 726, 726, 0, 0, 0, 0, 683, 724, 724, 724, 726, 726, 726, 726, 726, 726, 724, 724, 724, 724, 0, 0, 0, 0, 727, 727, 727, 0, 724, 724, 724, 724, 724, 724, 727, 0, 727, 0, 0, 0, 0, 0, 735, 735, 735, 0, 0, 0, 727, 0, 727, 735, 735, 735, 735, 0, 0, 0, 0, 0, 0, 0, 0, 735, 735, 735, 735, 735, 735, 0, 0, 0, 0, 0, 0, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 0, 0, 0, 724, 724, 724, 724, 0, 0, 0, 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, 727, 727, 727, 727, 0, 0, 0, 0, 727, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 748, 0, 748, 748, 748, 748, 748, 748, 748, 748, 748, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 751, 751, 0, 751, 751, 752, 752, 752, 752, 752, 752, 753, 753, 753, 753, 753, 753, 754, 754, 754, 755, 755, 755, 755, 755, 755, 756, 0, 756, 0, 756, 756, 756, 756, 756, 756, 756, 757, 0, 757, 757, 757, 757, 757, 757, 757, 757, 757, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 0, 759, 759, 759, 759, 759, 759, 759, 759, 759, 761, 761, 0, 761, 761, 762, 762, 762, 762, 762, 762, 763, 763, 763, 763, 763, 763, 764, 764, 764, 765, 765, 765, 765, 765, 765, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, 767, 0, 767, 767, 767, 767, 767, 767, 767, 767, 767, 768, 768, 768, 768, 768, 768, 769, 769, 769, 769, 769, 769, 770, 770, 770, 770, 770, 770, 771, 771, 771, 771, 771, 771, 772, 772, 772, 773, 0, 773, 0, 773, 773, 773, 773, 773, 773, 773, 774, 0, 774, 0, 0, 774, 774, 774, 774, 774, 774, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 777, 777, 777, 777, 777, 777, 778, 778, 778, 778, 778, 778, 779, 779, 779, 779, 779, 779, 780, 780, 780, 780, 780, 780, 781, 781, 781, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782, 783, 0, 783, 783, 783, 783, 783, 783, 783, 783, 783, 785, 785, 785, 785, 785, 785, 786, 786, 786, 786, 786, 786, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 790, 790, 790, 790, 790, 790, 791, 791, 791, 791, 791, 791, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 796, 796, 796, 796, 796, 796, 797, 797, 797, 797, 797, 797, 797, 797, 797, 797, 797, 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "cc.ll" #line 2 "cc.ll" /*-- Copyright (C) 2009 Jonathan Schmidt-Dominé -- Derived from the KDevelop-Java-Lexer -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Library General Public License for more details. -- -- You should have received a copy of the GNU Library General Public License -- along with this library; see the file COPYING.LIB. If not, write to -- the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA.*/ #line 27 "cc.ll" #define DONT_INCLUDE_FLEXLEXER #include "lexer.h" -#include +#include /* UTF-8 sequences, generated with the Unicode.hs script from * http://lists.gnu.org/archive/html/help-flex/2005-01/msg00043.html */ /* \u0024, \u0041-\u005a, \u005f, \u0061-\u007a: one byte in UTF-8 */ /* \u00c0-\u00d6, \u00d8-\u00f6, \u00f8-\u00ff */ /* \u0100-\u1fff */ /* \u3040-\u318f */ /* \u3300-\u337f */ /* \u3400-\u3d2d */ /* \u4e00-\u9fff */ /* \uf900-\ufaff */ /* \u0030-\u0039: ISO-LATIN-1 digits */ /* \u0660-\u0669, \u06f0-\u06f9: Arabic-Indic and extended Ar.-Indic digits */ /* \u0966-\u096f, \u09e6-\u09ef: Devanagari digits */ /* \u0a66-\u0a6f, \u0ae6-\u0aef */ /* \u0b66-\u0b6f, \u0be7-\u0bef */ /* \u0c66-\u0c6f, \u0ce6-\u0cef, \u0d66-\u0d6f */ /* \u0e50-\u0e59, \u0ed0-\u0ed9 */ /* \u1040-\u1049 */ /* \uff10-\uff19: Fullwidth digits */ /* \u0080-\uffff */ /* \u10000-\u1fffff */ /* \u200000-\u3ffffff */ /* \u4000000-\u7fffffff */ /* Any multi-byte Unicode character. Single-byte ones are just . in lex. */ /* non-Unicode stuff */ #line 2691 "cclexer.cpp" #define INITIAL 0 #define IN_BLOCKCOMMENT 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 122 "cc.ll" /* whitespace, newlines, preprocessor-statements and comments */ #line 2824 "cclexer.cpp" while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 746 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 8770 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 126 "cc.ll" /* skip */ ; YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 127 "cc.ll" /* skip */ ; YY_BREAK case 3: YY_RULE_SETUP #line 129 "cc.ll" /* line comments, skip */ ; YY_BREAK case 4: YY_RULE_SETUP #line 130 "cc.ll" /* preprocessor statement, skip */ ; YY_BREAK case 5: YY_RULE_SETUP #line 132 "cc.ll" BEGIN(IN_BLOCKCOMMENT); YY_BREAK case 6: YY_RULE_SETUP #line 134 "cc.ll" /* eat anything that's not a '*' */ ; YY_BREAK case 7: YY_RULE_SETUP #line 135 "cc.ll" /* eat up '*'s that are not followed by slashes or newlines */; YY_BREAK case 8: /* rule 8 can match eol */ YY_RULE_SETUP #line 136 "cc.ll" /* skip */ ; YY_BREAK case 9: YY_RULE_SETUP #line 137 "cc.ll" BEGIN(INITIAL); YY_BREAK case YY_STATE_EOF(IN_BLOCKCOMMENT): #line 138 "cc.ll" { qWarning() << "Encountered end of file in an unclosed block comment"; return Parser::Token_EOF; } YY_BREAK /* separators */ case 10: YY_RULE_SETUP #line 147 "cc.ll" return Parser::Token_LPAREN; YY_BREAK case 11: YY_RULE_SETUP #line 148 "cc.ll" return Parser::Token_RPAREN; YY_BREAK case 12: YY_RULE_SETUP #line 149 "cc.ll" return Parser::Token_LBRACE; YY_BREAK case 13: YY_RULE_SETUP #line 150 "cc.ll" return Parser::Token_RBRACE; YY_BREAK case 14: YY_RULE_SETUP #line 151 "cc.ll" return Parser::Token_LBRACKET; YY_BREAK case 15: YY_RULE_SETUP #line 152 "cc.ll" return Parser::Token_RBRACKET; YY_BREAK case 16: YY_RULE_SETUP #line 153 "cc.ll" return Parser::Token_COMMA; YY_BREAK case 17: YY_RULE_SETUP #line 154 "cc.ll" return Parser::Token_SEMICOLON; YY_BREAK case 18: YY_RULE_SETUP #line 155 "cc.ll" return Parser::Token_DOT; YY_BREAK case 19: YY_RULE_SETUP #line 156 "cc.ll" return Parser::Token_ARROW; YY_BREAK case 20: YY_RULE_SETUP #line 157 "cc.ll" return Parser::Token_COLON; YY_BREAK /* operators */ case 21: YY_RULE_SETUP #line 162 "cc.ll" return Parser::Token_QUESTION; YY_BREAK case 22: YY_RULE_SETUP #line 163 "cc.ll" return Parser::Token_NOT; YY_BREAK case 23: YY_RULE_SETUP #line 164 "cc.ll" return Parser::Token_TILDE; YY_BREAK case 24: YY_RULE_SETUP #line 165 "cc.ll" return Parser::Token_EQUAL_EQUAL; YY_BREAK case 25: YY_RULE_SETUP #line 166 "cc.ll" return Parser::Token_LESS; YY_BREAK case 26: YY_RULE_SETUP #line 167 "cc.ll" return Parser::Token_LESS_EQUAL; YY_BREAK case 27: YY_RULE_SETUP #line 168 "cc.ll" return Parser::Token_GREATER; YY_BREAK case 28: YY_RULE_SETUP #line 169 "cc.ll" return Parser::Token_GREATER_EQUAL; YY_BREAK case 29: YY_RULE_SETUP #line 170 "cc.ll" return Parser::Token_NOT_EQUAL; YY_BREAK case 30: YY_RULE_SETUP #line 171 "cc.ll" return Parser::Token_AND_AND; YY_BREAK case 31: YY_RULE_SETUP #line 172 "cc.ll" return Parser::Token_OR_OR; YY_BREAK case 32: YY_RULE_SETUP #line 173 "cc.ll" return Parser::Token_PLUS_PLUS; YY_BREAK case 33: YY_RULE_SETUP #line 174 "cc.ll" return Parser::Token_MINUS_MINUS; YY_BREAK case 34: YY_RULE_SETUP #line 175 "cc.ll" return Parser::Token_EQUAL; YY_BREAK case 35: YY_RULE_SETUP #line 176 "cc.ll" return Parser::Token_PLUS; YY_BREAK case 36: YY_RULE_SETUP #line 177 "cc.ll" return Parser::Token_PLUS_EQUAL; YY_BREAK case 37: YY_RULE_SETUP #line 178 "cc.ll" return Parser::Token_MINUS; YY_BREAK case 38: YY_RULE_SETUP #line 179 "cc.ll" return Parser::Token_MINUS_EQUAL; YY_BREAK case 39: YY_RULE_SETUP #line 180 "cc.ll" return Parser::Token_STAR; YY_BREAK case 40: YY_RULE_SETUP #line 181 "cc.ll" return Parser::Token_STAR_EQUAL; YY_BREAK case 41: YY_RULE_SETUP #line 182 "cc.ll" return Parser::Token_DIVIDE; YY_BREAK case 42: YY_RULE_SETUP #line 183 "cc.ll" return Parser::Token_DIVIDE_EQUAL; YY_BREAK case 43: YY_RULE_SETUP #line 184 "cc.ll" return Parser::Token_AND; YY_BREAK case 44: YY_RULE_SETUP #line 185 "cc.ll" return Parser::Token_AND_EQUAL; YY_BREAK case 45: YY_RULE_SETUP #line 186 "cc.ll" return Parser::Token_OR; YY_BREAK case 46: YY_RULE_SETUP #line 187 "cc.ll" return Parser::Token_OR_EQUAL; YY_BREAK case 47: YY_RULE_SETUP #line 188 "cc.ll" return Parser::Token_XOR; YY_BREAK case 48: YY_RULE_SETUP #line 189 "cc.ll" return Parser::Token_XOR_EQUAL; YY_BREAK case 49: YY_RULE_SETUP #line 190 "cc.ll" return Parser::Token_REMAINDER; YY_BREAK case 50: YY_RULE_SETUP #line 191 "cc.ll" return Parser::Token_REMAINDER_EQUAL; YY_BREAK case 51: YY_RULE_SETUP #line 192 "cc.ll" return Parser::Token_LSHIFT; YY_BREAK case 52: YY_RULE_SETUP #line 193 "cc.ll" return Parser::Token_LSHIFT_EQUAL; YY_BREAK case 53: YY_RULE_SETUP #line 194 "cc.ll" return Parser::Token_RSHIFT; YY_BREAK case 54: YY_RULE_SETUP #line 195 "cc.ll" return Parser::Token_RSHIFT_EQUAL; YY_BREAK case 55: YY_RULE_SETUP #line 196 "cc.ll" return Parser::Token_ELLIPSIS; YY_BREAK /* keywords */ case 56: YY_RULE_SETUP #line 200 "cc.ll" return Parser::Token_BREAK; YY_BREAK case 57: YY_RULE_SETUP #line 201 "cc.ll" return Parser::Token_CASE; YY_BREAK case 58: YY_RULE_SETUP #line 202 "cc.ll" return Parser::Token_CONTINUE; YY_BREAK case 59: YY_RULE_SETUP #line 203 "cc.ll" return Parser::Token_DEFAULT; YY_BREAK case 60: YY_RULE_SETUP #line 204 "cc.ll" return Parser::Token_DO; YY_BREAK case 61: YY_RULE_SETUP #line 205 "cc.ll" return Parser::Token_ELSE; YY_BREAK case 62: YY_RULE_SETUP #line 206 "cc.ll" return Parser::Token_ENUM; YY_BREAK case 63: YY_RULE_SETUP #line 207 "cc.ll" return Parser::Token_FOR; YY_BREAK case 64: YY_RULE_SETUP #line 208 "cc.ll" return Parser::Token_GOTO; YY_BREAK case 65: YY_RULE_SETUP #line 209 "cc.ll" return Parser::Token_IF; YY_BREAK case 66: YY_RULE_SETUP #line 210 "cc.ll" return Parser::Token_RETURN; YY_BREAK case 67: YY_RULE_SETUP #line 211 "cc.ll" return Parser::Token_SWITCH; YY_BREAK case 68: YY_RULE_SETUP #line 212 "cc.ll" return Parser::Token_WHILE; YY_BREAK case 69: YY_RULE_SETUP #line 213 "cc.ll" return Parser::Token_STATIC; YY_BREAK case 70: YY_RULE_SETUP #line 214 "cc.ll" return Parser::Token_VOLATILE; YY_BREAK case 71: YY_RULE_SETUP #line 215 "cc.ll" return Parser::Token_VOLATILE; YY_BREAK case 72: YY_RULE_SETUP #line 216 "cc.ll" return Parser::Token_CONST; YY_BREAK case 73: YY_RULE_SETUP #line 217 "cc.ll" return Parser::Token_TYPEDEF; YY_BREAK case 74: YY_RULE_SETUP #line 218 "cc.ll" return Parser::Token_EXTERN; YY_BREAK case 75: YY_RULE_SETUP #line 219 "cc.ll" return Parser::Token_AUTO; YY_BREAK case 76: YY_RULE_SETUP #line 220 "cc.ll" return Parser::Token_REGISTER; YY_BREAK case 77: YY_RULE_SETUP #line 221 "cc.ll" return Parser::Token_VOID; YY_BREAK case 78: YY_RULE_SETUP #line 222 "cc.ll" return Parser::Token_INT; YY_BREAK case 79: YY_RULE_SETUP #line 223 "cc.ll" return Parser::Token_CHAR; YY_BREAK case 80: YY_RULE_SETUP #line 224 "cc.ll" return Parser::Token_SHORT; YY_BREAK case 81: YY_RULE_SETUP #line 225 "cc.ll" return Parser::Token_LONG; YY_BREAK case 82: YY_RULE_SETUP #line 226 "cc.ll" return Parser::Token_SIGNED; YY_BREAK case 83: YY_RULE_SETUP #line 227 "cc.ll" return Parser::Token_UNSIGNED; YY_BREAK case 84: YY_RULE_SETUP #line 228 "cc.ll" return Parser::Token_FLOAT; YY_BREAK case 85: YY_RULE_SETUP #line 229 "cc.ll" return Parser::Token_DOUBLE; YY_BREAK case 86: YY_RULE_SETUP #line 230 "cc.ll" return Parser::Token_UNION; YY_BREAK case 87: YY_RULE_SETUP #line 231 "cc.ll" return Parser::Token_ASM; YY_BREAK case 88: YY_RULE_SETUP #line 232 "cc.ll" return Parser::Token_ASM; YY_BREAK case 89: YY_RULE_SETUP #line 233 "cc.ll" return Parser::Token_EXTENSION; YY_BREAK case 90: YY_RULE_SETUP #line 234 "cc.ll" return Parser::Token_INLINE; YY_BREAK case 91: YY_RULE_SETUP #line 235 "cc.ll" return Parser::Token_INLINE; YY_BREAK /* characters and strings (C with unicode-support) */ case 92: YY_RULE_SETUP #line 239 "cc.ll" return Parser::Token_X_CONSTANT; YY_BREAK case 93: /* rule 93 can match eol */ YY_RULE_SETUP #line 240 "cc.ll" { qWarning() << QString("Invalid character literal: %1").arg(yytext); return Parser::Token_X_CONSTANT; } YY_BREAK case 94: YY_RULE_SETUP #line 245 "cc.ll" return Parser::Token_STRING_LITERAL; YY_BREAK case 95: /* rule 95 can match eol */ YY_RULE_SETUP #line 246 "cc.ll" { qWarning() << QString("Invalid string literal: %1").arg(yytext); return Parser::Token_STRING_LITERAL; } YY_BREAK /* identifiers and number literals */ case 96: YY_RULE_SETUP #line 254 "cc.ll" return Parser::Token_IDENTIFIER; YY_BREAK case 97: YY_RULE_SETUP #line 256 "cc.ll" return Parser::Token_X_CONSTANT; YY_BREAK case 98: YY_RULE_SETUP #line 257 "cc.ll" return Parser::Token_X_CONSTANT; YY_BREAK /* everything else is not a valid lexeme */ case 99: YY_RULE_SETUP #line 262 "cc.ll" { qWarning() << "INVALID TOKEN"; exit(-1); } YY_BREAK case 100: YY_RULE_SETUP #line 267 "cc.ll" ECHO; YY_BREAK #line 3409 "cclexer.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; yyfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); yyfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) #else int yyFlexLexer::LexerInput( char* buf, int max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, int size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 746 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 746 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 745); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) yyalloc(new_size ); else (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 267 "cc.ll" namespace cc { Lexer::Lexer( Parser *parser, char *contents ) { restart( parser, contents ); } void Lexer::restart( Parser *parser, char *contents ) { m_parser = parser; m_locationTable = parser->tokenStream->locationTable(); m_contents = contents; m_tokenBegin = m_tokenEnd = 0; m_currentOffset = 0; // check for and ignore the UTF-8 byte order mark unsigned char *ucontents = (unsigned char *) m_contents; if ( ucontents[0] == 0xEF && ucontents[1] == 0xBB && ucontents[2] == 0xBF ) { m_tokenBegin = m_tokenEnd = 3; m_currentOffset = 3; } yyrestart(NULL); BEGIN(INITIAL); // is not set automatically by yyrestart() } // reads a character, and returns 1 as the number of characters read // (or 0 when the end of the string is reached) int Lexer::LexerInput( char *buf, int /*max_size*/ ) { int c = m_contents[ m_currentOffset++ ]; switch(c) { case '\r': c = '\n'; // only have one single line break character: '\n' if ( m_contents[m_currentOffset + 1] == '\n' ) { m_currentOffset++; m_tokenEnd++; } // fall through case '\n': m_locationTable->newline( m_currentOffset - 1 ); break; default: break; } return (c == 0) ? 0 : (buf[0] = c, 1); } } // end of namespace cc diff --git a/examples/cc/dumptree.cpp b/examples/cc/dumptree.cpp index e37812d..51efa7d 100644 --- a/examples/cc/dumptree.cpp +++ b/examples/cc/dumptree.cpp @@ -1,140 +1,140 @@ /* (C) Copyright 2009 Jonathan Schmidt-Dominé Derived from the KDevelop-Java-Parser This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dumptree.h" #include "ccast.h" #include "kdev-pg-token-stream.h" -#include +#include #include static char const * const names[] = { "AND_expression", "Abstract_declarator", "Additive_expression", "Argument_expression_list", "Asm_against_mangling", "Asm_specifier", "Assignment_expression", "Assignment_operator", "Cast_expression", "Compound_statement", "Conditional_expression", "Constant", "Constant_expression", "Ddeclaration", "Declaration", "Declaration_header", "Declaration_parameter", "Declaration_specifier", "Declarator", "Direct_abstract_declarator", "Direct_declarator", "Direct_declarator_rest", "Document", "Enum_specifier", "Enumerator", "Equality_expression", "Exclusive_OR_expression", "Execution_block", "Expression", "Expression_statement", "Ext_expression", "External_Block", "External_declaration", "Function_declaration", "Function_definition", "Inclusive_OR_expression", "Init_declarator", "Initializer", "Inline_asm", "Iteration_statement", "Jump_statement", "Labeled_statement", "Logical_AND_expression", "Logical_OR_expression", "Multiplicative_expression", "Named_parameter", "Parameter", "Parameter_declaration", "Parameter_type_list", "Pointer", "Postfix_expression", "Postfix_expression_rest", "Primary_expression", "Relational_expression", "Selection_statement", "Shift_expression", "Specifier_qualifier", "Statement", "Storage_class_specifier", "Struct_declaration", "Struct_declarator", "Struct_or_union_specifier", "Translation_unit", "Type_name", "Type_name_d", "Type_qualifier", "Type_specifier", "Typed_identifier", "Typedef_d", "Unary_expression", "Unary_operator", "Value_Declaration", "Variable_declaration", "Variable_or_function" }; using namespace cc; DumpTree::DumpTree() : indent(0) { } void DumpTree::dump( AstNode * node ) { visitNode(node); } void DumpTree::visitNode(AstNode *node) { QString nodeText; if (node) { std::cout << QString(indent * 2, ' ').toLatin1().constData() << names[node->kind - 1000] << "[" << node->startToken << "," << node->endToken << "]" << nodeText.toLatin1().constData() << std::endl; } ++indent; DefaultVisitor::visitNode(node); --indent; if (node) { std::cout << QString(indent * 2, ' ').toLatin1().constData() << names[node->kind - 1000] << std::endl; } } DumpTree::~DumpTree( ) { } diff --git a/examples/cool/cool.g b/examples/cool/cool.g index b59ec31..a78ea83 100644 --- a/examples/cool/cool.g +++ b/examples/cool/cool.g @@ -1,203 +1,203 @@ [: -#include +#include :] ------------------------------------------------------------ -- Parser class members ------------------------------------------------------------ %parserclass (private declaration) [: QString m_contents; :] %parserclass (public declaration) [: /** * Transform the raw input into tokens. * When this method returns, the parser's token stream has been filled * and any parse_*() method can be called. */ void tokenize( char *contents ); enum problem_type { error, warning, info }; // void report_problem( Parser::problem_type type, const char* message ); void report_problem( Parser::problem_type type, const QString & message ); QString tokenText(qint64 begin, qint64 end); :] %parser_declaration_header "coolast.h" ------------------------------------------------------------ -- List of defined tokens ------------------------------------------------------------ -- keywords: %token CLASS ("class"), INHERITS ("inherits"), NEW ("new"), IF ("if"), THEN ("then"), ELSE ("else"), FI ("fi"), WHILE ("while"), LOOP ("loop"), POOL ("pool"), LET ("let"), IN ("in"), CASE ("case"), OF ("of"), ESAC ("esac") ;; -- seperators: %token LPAREN ("("), RPAREN (")"), LBRACE ("{"), RBRACE ("}"), SEMICOLON (";"), COMMA (","), DOT ("."), AT ("@") ;; -- operators: %token PLUS ("+"), MINUS ("-"), STAR ("*"), SLASH ("/"), EQUAL ("="), LESS_EQUAL ("<="), LESS ("<"), COLON (":"), ARROW_LEFT ("<-"), ARROW_RIGHT ("=>"), TILDE ("~"), NOT ("not"), ISVOID ("isvoid") ;; -- literals and identifiers: %token IDENTIFIER ("identifier"), TYPE ("type specification"), INTEGER ("integer literal"), STRING ("string literal"), TRUE ("true"), FALSE ("false") ;; -- token that makes the parser fail in any case: %token INVALID ("invalid token") ;; ------------------------------------------------------------ -- Start of the actual grammar ------------------------------------------------------------ (#klass=class SEMICOLON)* -> program ;; CLASS type=TYPE (INHERITS base_type=TYPE | 0) LBRACE (#feature=feature SEMICOLON)* RBRACE -> class ;; name=IDENTIFIER COLON type=TYPE -> formal ;; ( ?[: LA(2).kind == Token_LPAREN :] name=IDENTIFIER LPAREN (#formal=formal @ COMMA | 0) RPAREN COLON type=TYPE LBRACE expression=expression RBRACE | name=IDENTIFIER COLON type=TYPE (ARROW_LEFT expression=expression | 0) ) -> feature ;; ( ?[: LA(2).kind == Token_ARROW_LEFT :] name=IDENTIFIER ARROW_LEFT expression=expression -- assignment | ?[: LA(2).kind == Token_LPAREN :] name=IDENTIFIER LPAREN (#argument=expression @ COMMA | 0) RPAREN -- dispatch | variable=IDENTIFIER | integer_literal=INTEGER | string_literal=STRING | true_literal=TRUE | false_literal=FALSE | NEW new_type=TYPE | LPAREN expression=expression RPAREN | if_expression=if_expression | while_expression=while_expression | block_expression=block_expression | let_expression=let_expression | case_expression=case_expression ) -> primary_expression ;; op=TILDE expression=primary_expression -- ^tilde_expression | op=NOT expression=primary_expression -- ^not_expression | op=ISVOID expression=primary_expression -- ^isvoid_expression | expression=primary_expression -> unary_expression ;; base_expression=unary_expression (AT at_type=TYPE DOT name=IDENTIFIER LPAREN (#arguments=expression @ COMMA | 0) RPAREN | DOT name=IDENTIFIER LPAREN (#arguments=expression @ COMMA | 0) RPAREN )* -> postfix_expression ;; #expression=postfix_expression @ (op=STAR | op=SLASH) -> multiplicative_expression ;; #expression=multiplicative_expression @ (op=PLUS | op=MINUS) -> additive_expression ;; #expression=additive_expression @ (op=EQUAL | op=LESS_EQUAL | op=LESS) -> relational_expression ;; IF condition=expression THEN true_expression=expression ELSE false_expression=expression FI -> if_expression ;; WHILE condition=expression LOOP loop_expression=expression POOL -> while_expression ;; LBRACE (#expression=expression SEMICOLON)* RBRACE -> block_expression ;; LET #declaration=let_declaration @ COMMA IN body_expression=expression -> let_expression ;; CASE expression=expression OF (#condition=case_condition SEMICOLON)* ESAC -> case_expression ;; .=relational_expression -> expression ;; name=IDENTIFIER COLON type=TYPE (ARROW_LEFT expression=expression | 0) -> let_declaration ;; name=IDENTIFIER COLON type=TYPE ARROW_RIGHT expression=expression -> case_condition ;; ----------------------------------------------------------------- -- Code segments copied to the implementation (.cpp) file. -- If existent, kdevelop-pg's current syntax requires this block -- to occur at the end of the file. ----------------------------------------------------------------- [: #include "cool_lexer.h" namespace cool { void Parser::tokenize( char *contents ) { m_contents = contents; Lexer lexer( this, contents ); int kind = Parser::Token_EOF; do { kind = lexer.yylex(); //std::cerr << lexer.YYText() << std::endl; //" "; // debug output if ( !kind ) // when the lexer returns 0, the end of file is reached kind = Parser::Token_EOF; Parser::Token &t = this->tokenStream->push(); t.kind = kind; t.begin = lexer.tokenBegin(); t.end = lexer.tokenEnd(); // t.text = contents; } while ( kind != Parser::Token_EOF ); this->yylex(); // produce the look ahead token } QString Parser::tokenText(qint64 begin, qint64 end) { return m_contents.mid(begin,end-begin+1); } } // end of namespace cool :] diff --git a/examples/cool/cool_lexer.h b/examples/cool/cool_lexer.h index 2a9b8e6..1103a19 100644 --- a/examples/cool/cool_lexer.h +++ b/examples/cool/cool_lexer.h @@ -1,70 +1,70 @@ /****************************************************************************** * Copyright (c) 2005, 2006 Jakob Petsovits * * * * Permission to use, copy, modify, distribute, and sell this software and * * its documentation for any purpose is hereby granted without fee, provided * * that the above copyright notice appear in all copies and that both that * * copyright notice and this permission notice appear in supporting * * documentation. * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *****************************************************************************/ #include "coolparser.h" #include -#include +#include #include #ifndef DONT_INCLUDE_FLEXLEXER #include #endif // The YY_USER_ACTION macro is called whenever a token is found by Flex #define YY_USER_ACTION \ m_tokenBegin = m_tokenEnd; \ m_tokenEnd += yyleng; namespace cool { class Lexer : public yyFlexLexer { public: Lexer( cool::Parser *parser, char *contents ); void restart( cool::Parser *parser, char *contents ); int yylex(); char *contents() { return m_contents; } std::size_t tokenBegin() { return m_tokenBegin; } std::size_t tokenEnd() { return m_tokenEnd; } protected: // custom input, replacing the Flex default input stdin virtual int LexerInput( char *buf, int max_size ); // dismisses any lexer output (which should not happen anyways) virtual void LexerOutput( const char * /*buf*/, int /*max_size*/ ) { return; } virtual void LexerError( const char */*msg*/ ) { return; } private: cool::Parser* m_parser; char *m_contents; std::size_t m_tokenBegin, m_tokenEnd; std::size_t m_currentOffset; KDevPG::LocationTable *m_locationTable; }; } // end of namespace cool // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/examples/fact/fact.g b/examples/fact/fact.g index 9e40180..d7bf3fe 100644 --- a/examples/fact/fact.g +++ b/examples/fact/fact.g @@ -1,236 +1,236 @@ ----------------------------------------------------------- -- Global declarations ----------------------------------------------------------- [: -#include +#include namespace fact { class Lexer; } :] ------------------------------------------------------------ -- Parser class members ------------------------------------------------------------ %parserclass (public declaration) [: /** * Transform the raw input into tokens. * When this method returns, the parser's token stream has been filled * and any parse_*() method can be called. */ void tokenize( const QString& contents ); enum ProblemType { Error, Warning, Info }; void reportProblem( Parser::ProblemType type, const QString& message ); QString tokenText(qint64 begin, qint64 end) const; void setDebug( bool debug ); :] %parserclass (private declaration) [: QString m_contents; bool m_debug; :] ------------------------------------------------------------ -- List of defined tokens ------------------------------------------------------------ %token FUNCTION ("function"), VAR ("var"), IF ("if"), ELSE ("else"), RETURN ("return") ;; %token LPAREN ("("), RPAREN (")"), LBRACE ("{"), RBRACE ("}"), COMMA (","), SEMICOLON (";") ;; %token ASSIGN ("="), EQUAL ("=="), STAR ("*"), MINUS ("-") ;; %token IDENTIFIER ("identifier"), NUMBER ("integer literal") ;; %token INVALID ("invalid token") ;; ------------------------------------------------------------ -- Start of the actual grammar ------------------------------------------------------------ -- Declaration rules ---------------------- (#fun=functionDefinition)* -> program ;; FUNCTION id=IDENTIFIER LPAREN (#param=IDENTIFIER @ COMMA | 0) RPAREN body=body -> functionDefinition ;; LBRACE (#decl=declaration)* (#stmt=statement)* RBRACE -> body ;; VAR (var=variable @ COMMA) SEMICOLON -> declaration ;; id=IDENTIFIER -> variable ;; -- Statement rules -------------------- id=IDENTIFIER ASSIGN expr=expression SEMICOLON -> assignmentStatement ;; IF LPAREN cond=condition RPAREN ifStmt=statement (ELSE elseStmt=statement | 0) -> ifStatement ;; LBRACE (#stmt=statement)* RBRACE -> blockStatement ;; RETURN expr=expression SEMICOLON -> returnStatement ;; assignStmt=assignmentStatement | ifStmt=ifStatement | blockStmt=blockStatement | returnStmt=returnStatement -> statement ;; -- Expression rules -------------------- num=NUMBER | id=IDENTIFIER (LPAREN (#argument=expression @ COMMA) RPAREN | 0) -> primary ;; leftExpr=primary (STAR rightExpr=primary)* -> multExpression ;; leftExpr=multExpression (MINUS rightExpr=multExpression)* -> expression ;; leftExpr=expression EQUAL rightExpr=expression -> condition ;; ----------------------------------------------------------------- -- Code segments copied to the implementation (.cpp) file. -- If existent, kdevelop-pg's current syntax requires this block -- to occur at the end of the file. ----------------------------------------------------------------- [: #include "factlexer.h" -#include +#include #include namespace fact { void Parser::tokenize( const QString& contents ) { m_contents = contents; Lexer lexer( this, contents ); int kind = Parser::Token_EOF; do { kind = lexer.nextTokenKind(); if ( !kind ) // when the lexer returns 0, the end of file is reached kind = Parser::Token_EOF; Parser::Token &t = tokenStream->next(); t.kind = kind; if( t.kind == Parser::Token_EOF ) { t.begin = -1; t.end = -1; } else { t.begin = lexer.tokenBegin(); t.end = lexer.tokenEnd(); } if( m_debug ) { qDebug() << kind << "(" << t.begin << "," << t.end << ")::" << tokenText(t.begin, t.end); } } while ( kind != Parser::Token_EOF ); this->yylex(); // produce the look ahead token } QString Parser::tokenText( qint64 begin, qint64 end ) const { return m_contents.mid((int)begin, (int)end-begin+1); } void Parser::reportProblem( Parser::ProblemType type, const QString& message ) { if (type == Error) qDebug() << "** ERROR:" << message; else if (type == Warning) qDebug() << "** WARNING:" << message; else if (type == Info) qDebug() << "** Info:" << message; } // custom error recovery void Parser::expectedToken(int /*expected*/, qint64 /*where*/, const QString& name) { reportProblem( Parser::Error, QString("Expected token \"%1\"").arg(name)); } void Parser::expectedSymbol(int /*expected_symbol*/, const QString& name) { qint64 line; qint64 col; size_t index = tokenStream->index()-1; Token &token = tokenStream->token(index); qDebug() << "token starts at:" << token.begin; qDebug() << "index is:" << index; tokenStream->startPosition(index, &line, &col); QString tokenValue = tokenText(token.begin, token.end); reportProblem( Parser::Error, QString("Expected symbol \"%1\" (current token: \"%2\" [%3] at line: %4 col: %5)") .arg(name) .arg(token.kind != 0 ? tokenValue : "EOF") .arg(token.kind) .arg(line) .arg(col)); } void Parser::setDebug( bool debug ) { m_debug = debug; } } // end of namespace fact :] -- kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/examples/fact/factast.h b/examples/fact/factast.h index 49d2c17..10fbc53 100644 --- a/examples/fact/factast.h +++ b/examples/fact/factast.h @@ -1,182 +1,182 @@ // THIS FILE IS GENERATED // WARNING! All changes made in this file will be lost! #ifndef FACT_AST_H_INCLUDED #define FACT_AST_H_INCLUDED -#include +#include #include -#include +#include namespace fact { class Lexer; } namespace fact { struct AssignmentStatementAst; struct BlockStatementAst; struct BodyAst; struct ConditionAst; struct DeclarationAst; struct ExpressionAst; struct FunctionDefinitionAst; struct IfStatementAst; struct MultExpressionAst; struct PrimaryAst; struct ProgramAst; struct ReturnStatementAst; struct StatementAst; struct VariableAst; struct AstNode { enum AstNodeKind { AssignmentStatementKind = 1000, BlockStatementKind = 1001, BodyKind = 1002, ConditionKind = 1003, DeclarationKind = 1004, ExpressionKind = 1005, FunctionDefinitionKind = 1006, IfStatementKind = 1007, MultExpressionKind = 1008, PrimaryKind = 1009, ProgramKind = 1010, ReturnStatementKind = 1011, StatementKind = 1012, VariableKind = 1013, AST_NODE_KIND_COUNT }; int kind; qint64 startToken; qint64 endToken; }; struct AssignmentStatementAst: public AstNode { enum { KIND = AssignmentStatementKind }; qint64 id; ExpressionAst *expr; }; struct BlockStatementAst: public AstNode { enum { KIND = BlockStatementKind }; const KDevPG::ListNode *stmtSequence; }; struct BodyAst: public AstNode { enum { KIND = BodyKind }; const KDevPG::ListNode *declSequence; const KDevPG::ListNode *stmtSequence; }; struct ConditionAst: public AstNode { enum { KIND = ConditionKind }; ExpressionAst *leftExpr; ExpressionAst *rightExpr; }; struct DeclarationAst: public AstNode { enum { KIND = DeclarationKind }; VariableAst *var; }; struct ExpressionAst: public AstNode { enum { KIND = ExpressionKind }; MultExpressionAst *leftExpr; MultExpressionAst *rightExpr; }; struct FunctionDefinitionAst: public AstNode { enum { KIND = FunctionDefinitionKind }; qint64 id; const KDevPG::ListNode *paramSequence; BodyAst *body; }; struct IfStatementAst: public AstNode { enum { KIND = IfStatementKind }; ConditionAst *cond; StatementAst *ifStmt; StatementAst *elseStmt; }; struct MultExpressionAst: public AstNode { enum { KIND = MultExpressionKind }; PrimaryAst *leftExpr; PrimaryAst *rightExpr; }; struct PrimaryAst: public AstNode { enum { KIND = PrimaryKind }; qint64 num; qint64 id; const KDevPG::ListNode *argumentSequence; }; struct ProgramAst: public AstNode { enum { KIND = ProgramKind }; const KDevPG::ListNode *funSequence; }; struct ReturnStatementAst: public AstNode { enum { KIND = ReturnStatementKind }; ExpressionAst *expr; }; struct StatementAst: public AstNode { enum { KIND = StatementKind }; AssignmentStatementAst *assignStmt; IfStatementAst *ifStmt; BlockStatementAst *blockStmt; ReturnStatementAst *returnStmt; }; struct VariableAst: public AstNode { enum { KIND = VariableKind }; qint64 id; }; } // end of namespace fact #endif diff --git a/examples/fact/factlexer.cpp b/examples/fact/factlexer.cpp index d0d28cb..405cbb4 100644 --- a/examples/fact/factlexer.cpp +++ b/examples/fact/factlexer.cpp @@ -1,191 +1,191 @@ /* * Copyright 2005, 2006 Jakob Petsovits * Based on QMake Parser Copyright 2006 Andreas Pakulat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "factlexer.h" -#include -#include -#include +#include +#include +#include #include "factparser.h" #include #include using namespace fact; Lexer::Lexer( Parser* _parser, const QString& content ): m_content( content ), m_parser( _parser ), m_curpos( 0 ), m_contentSize( m_content.size() ), m_tokenBegin( 0 ), m_tokenEnd( 0 ) { pushState( ErrorState ); pushState( DefaultState ); } int Lexer::state() const { return mState.top(); } void Lexer::pushState( int state ) { mState.push( state ); } void Lexer::popState() { mState.pop(); } int Lexer::nextTokenKind() { int token = Parser::Token_INVALID; if ( m_curpos >= m_contentSize ) { return 0; } QChar* it = m_content.data(); it += m_curpos; // Ignore whitespace while ( m_curpos < m_contentSize && ( it->isSpace() ) ) { if (it->unicode() == '\n') { createNewline(m_curpos); } ++it; ++m_curpos; } switch ( state() ) { case DefaultState: m_tokenBegin = m_curpos; if ( m_curpos < m_contentSize ) { if ( it->isLetter() ) { QString identifier; while ( m_curpos < m_contentSize && ( it->isLetter() || it->isDigit() ) && !it->isSpace() ) { identifier.append(*it); ++it; ++m_curpos; } m_curpos--; QChar* it1 = m_content.data(); it1 += m_curpos; if ( identifier == "if" ) { token = Parser::Token_IF; } else if ( identifier == "else" ) { token = Parser::Token_ELSE; } else if ( identifier == "var" ) { token = Parser::Token_VAR; } else if ( identifier == "function" ) { token = Parser::Token_FUNCTION; } else if ( identifier == "return" ) { token = Parser::Token_RETURN; } else { token = Parser::Token_IDENTIFIER; } } else if ( it->isDigit() ) { token = Parser::Token_NUMBER; while ( m_curpos < m_contentSize && ( it->isDigit() ) ) { ++it; ++m_curpos; } --m_curpos; } else { switch ( it->unicode() ) { case ',': token = Parser::Token_COMMA; break; case ';': token = Parser::Token_SEMICOLON; break; case '(': token = Parser::Token_LPAREN; break; case ')': token = Parser::Token_RPAREN; break; case '{': token = Parser::Token_LBRACE; break; case '}': token = Parser::Token_RBRACE; break; case '=': { QChar* c2 = m_curpos < m_contentSize ? it + 1 : 0 ; if ( c2 && c2->unicode() == '=' ) { m_curpos++; token = Parser::Token_EQUAL; } else { token = Parser::Token_ASSIGN; } break; } case '*': token = Parser::Token_STAR; break; case '-': token = Parser::Token_MINUS; break; default: break; } } } break; default: token = Parser::Token_INVALID; break; } if ( m_curpos >= m_contentSize ) { return 0; } m_tokenEnd = m_curpos; m_curpos++; return token; } qint64 Lexer::tokenBegin() const { return m_tokenBegin; } qint64 Lexer::tokenEnd() const { return m_tokenEnd; } void Lexer::createNewline( int pos ) { if( m_parser ) m_parser->tokenStream->locationTable()->newline( pos ); } // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/examples/fact/factlexer.h b/examples/fact/factlexer.h index 6608395..a053643 100644 --- a/examples/fact/factlexer.h +++ b/examples/fact/factlexer.h @@ -1,64 +1,64 @@ /* * Copyright 2008 Niko Sams * Based on QMake Parser Copyright 2006 Andreas Pakulat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "factparser.h" -#include -#include +#include +#include namespace fact { class Parser; class Lexer { public: Lexer( fact::Parser *parser, const QString& contents); int nextTokenKind(); qint64 tokenBegin() const; qint64 tokenEnd() const; private: QString m_content; Parser* m_parser; int m_curpos; int m_contentSize; qint64 m_tokenBegin; qint64 m_tokenEnd; int state() const; void pushState(int state); void popState(); void createNewline( int pos ); QStack mState; enum State { ErrorState = -1, DefaultState = 0 }; }; } // end of namespace fact // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/examples/fact/factparser.cpp b/examples/fact/factparser.cpp index fb62cce..c5a7b2c 100644 --- a/examples/fact/factparser.cpp +++ b/examples/fact/factparser.cpp @@ -1,901 +1,901 @@ // THIS FILE IS GENERATED // WARNING! All changes made in this file will be lost! #include "factparser.h" #include "factlexer.h" -#include +#include #include namespace fact { void Parser::tokenize( const QString& contents ) { m_contents = contents; Lexer lexer( this, contents ); int kind = Parser::Token_EOF; do { kind = lexer.nextTokenKind(); if ( !kind ) // when the lexer returns 0, the end of file is reached kind = Parser::Token_EOF; Parser::Token &t = tokenStream->next(); t.kind = kind; if ( t.kind == Parser::Token_EOF ) { t.begin = -1; t.end = -1; } else { t.begin = lexer.tokenBegin(); t.end = lexer.tokenEnd(); } if ( m_debug ) { qDebug() << kind << "(" << t.begin << "," << t.end << ")::" << tokenText(t.begin, t.end); } } while ( kind != Parser::Token_EOF ); this->yylex(); // produce the look ahead token } QString Parser::tokenText( qint64 begin, qint64 end ) const { return m_contents.mid((int)begin, (int)end-begin+1); } void Parser::reportProblem( Parser::ProblemType type, const QString& message ) { if (type == Error) qDebug() << "** ERROR:" << message; else if (type == Warning) qDebug() << "** WARNING:" << message; else if (type == Info) qDebug() << "** Info:" << message; } // custom error recovery void Parser::expectedToken(int /*expected*/, qint64 /*where*/, const QString& name) { reportProblem( Parser::Error, QString("Expected token \"%1\"").arg(name)); } void Parser::expectedSymbol(int /*expected_symbol*/, const QString& name) { qint64 line; qint64 col; size_t index = tokenStream->index()-1; Token &token = tokenStream->token(index); qDebug() << "token starts at:" << token.begin; qDebug() << "index is:" << index; tokenStream->startPosition(index, &line, &col); QString tokenValue = tokenText(token.begin, token.end); reportProblem( Parser::Error, QString("Expected symbol \"%1\" (current token: \"%2\" [%3] at line: %4 col: %5)") .arg(name) .arg(token.kind != 0 ? tokenValue : "EOF") .arg(token.kind) .arg(line) .arg(col)); } void Parser::setDebug( bool debug ) { m_debug = debug; } } // end of namespace fact namespace fact { bool Parser::parseAssignmentStatement(AssignmentStatementAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; (*yynode)->id = -1; if (yytoken == Token_IDENTIFIER) { if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->id = tokenStream->index() - 1; yylex(); if (yytoken != Token_ASSIGN) { expectedToken(yytoken, Token_ASSIGN, "="); return false; } yylex(); ExpressionAst *__node_0 = 0; if (!parseExpression(&__node_0)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->expr = __node_0; if (yytoken != Token_SEMICOLON) { expectedToken(yytoken, Token_SEMICOLON, ";"); return false; } yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseBlockStatement(BlockStatementAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_LBRACE) { if (yytoken != Token_LBRACE) { expectedToken(yytoken, Token_LBRACE, "{"); return false; } yylex(); while (yytoken == Token_IF || yytoken == Token_IDENTIFIER || yytoken == Token_RETURN || yytoken == Token_LBRACE) { StatementAst *__node_1 = 0; if (!parseStatement(&__node_1)) { expectedSymbol(AstNode::StatementKind, "statement"); return false; } (*yynode)->stmtSequence = snoc((*yynode)->stmtSequence, __node_1, memoryPool); } if (yytoken != Token_RBRACE) { expectedToken(yytoken, Token_RBRACE, "}"); return false; } yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseBody(BodyAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_LBRACE) { if (yytoken != Token_LBRACE) { expectedToken(yytoken, Token_LBRACE, "{"); return false; } yylex(); while (yytoken == Token_VAR) { DeclarationAst *__node_2 = 0; if (!parseDeclaration(&__node_2)) { expectedSymbol(AstNode::DeclarationKind, "declaration"); return false; } (*yynode)->declSequence = snoc((*yynode)->declSequence, __node_2, memoryPool); } while (yytoken == Token_IF || yytoken == Token_IDENTIFIER || yytoken == Token_RETURN || yytoken == Token_LBRACE) { StatementAst *__node_3 = 0; if (!parseStatement(&__node_3)) { expectedSymbol(AstNode::StatementKind, "statement"); return false; } (*yynode)->stmtSequence = snoc((*yynode)->stmtSequence, __node_3, memoryPool); } if (yytoken != Token_RBRACE) { expectedToken(yytoken, Token_RBRACE, "}"); return false; } yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseCondition(ConditionAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_NUMBER || yytoken == Token_IDENTIFIER) { ExpressionAst *__node_4 = 0; if (!parseExpression(&__node_4)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->leftExpr = __node_4; if (yytoken != Token_EQUAL) { expectedToken(yytoken, Token_EQUAL, "=="); return false; } yylex(); ExpressionAst *__node_5 = 0; if (!parseExpression(&__node_5)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->rightExpr = __node_5; } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseDeclaration(DeclarationAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_VAR) { if (yytoken != Token_VAR) { expectedToken(yytoken, Token_VAR, "var"); return false; } yylex(); VariableAst *__node_6 = 0; if (!parseVariable(&__node_6)) { expectedSymbol(AstNode::VariableKind, "variable"); return false; } (*yynode)->var = __node_6; while (yytoken == Token_COMMA) { if (yytoken != Token_COMMA) { expectedToken(yytoken, Token_COMMA, ","); return false; } yylex(); VariableAst *__node_7 = 0; if (!parseVariable(&__node_7)) { expectedSymbol(AstNode::VariableKind, "variable"); return false; } (*yynode)->var = __node_7; } if (yytoken != Token_SEMICOLON) { expectedToken(yytoken, Token_SEMICOLON, ";"); return false; } yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseExpression(ExpressionAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_NUMBER || yytoken == Token_IDENTIFIER) { MultExpressionAst *__node_8 = 0; if (!parseMultExpression(&__node_8)) { expectedSymbol(AstNode::MultExpressionKind, "multExpression"); return false; } (*yynode)->leftExpr = __node_8; while (yytoken == Token_MINUS) { if (yytoken != Token_MINUS) { expectedToken(yytoken, Token_MINUS, "-"); return false; } yylex(); MultExpressionAst *__node_9 = 0; if (!parseMultExpression(&__node_9)) { expectedSymbol(AstNode::MultExpressionKind, "multExpression"); return false; } (*yynode)->rightExpr = __node_9; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseFunctionDefinition(FunctionDefinitionAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; (*yynode)->id = -1; if (yytoken == Token_FUNCTION) { if (yytoken != Token_FUNCTION) { expectedToken(yytoken, Token_FUNCTION, "function"); return false; } yylex(); if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->id = tokenStream->index() - 1; yylex(); if (yytoken != Token_LPAREN) { expectedToken(yytoken, Token_LPAREN, "("); return false; } yylex(); if (yytoken == Token_IDENTIFIER) { if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->paramSequence = snoc((*yynode)->paramSequence, tokenStream->index() - 1, memoryPool); yylex(); while (yytoken == Token_COMMA) { if (yytoken != Token_COMMA) { expectedToken(yytoken, Token_COMMA, ","); return false; } yylex(); if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->paramSequence = snoc((*yynode)->paramSequence, tokenStream->index() - 1, memoryPool); yylex(); } } else if (true /*epsilon*/) { } else { return false; } if (yytoken != Token_RPAREN) { expectedToken(yytoken, Token_RPAREN, ")"); return false; } yylex(); BodyAst *__node_10 = 0; if (!parseBody(&__node_10)) { expectedSymbol(AstNode::BodyKind, "body"); return false; } (*yynode)->body = __node_10; } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseIfStatement(IfStatementAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_IF) { if (yytoken != Token_IF) { expectedToken(yytoken, Token_IF, "if"); return false; } yylex(); if (yytoken != Token_LPAREN) { expectedToken(yytoken, Token_LPAREN, "("); return false; } yylex(); ConditionAst *__node_11 = 0; if (!parseCondition(&__node_11)) { expectedSymbol(AstNode::ConditionKind, "condition"); return false; } (*yynode)->cond = __node_11; if (yytoken != Token_RPAREN) { expectedToken(yytoken, Token_RPAREN, ")"); return false; } yylex(); StatementAst *__node_12 = 0; if (!parseStatement(&__node_12)) { expectedSymbol(AstNode::StatementKind, "statement"); return false; } (*yynode)->ifStmt = __node_12; if (yytoken == Token_ELSE) { if (yytoken != Token_ELSE) { expectedToken(yytoken, Token_ELSE, "else"); return false; } yylex(); StatementAst *__node_13 = 0; if (!parseStatement(&__node_13)) { expectedSymbol(AstNode::StatementKind, "statement"); return false; } (*yynode)->elseStmt = __node_13; } else if (true /*epsilon*/) { } else { return false; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseMultExpression(MultExpressionAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_NUMBER || yytoken == Token_IDENTIFIER) { PrimaryAst *__node_14 = 0; if (!parsePrimary(&__node_14)) { expectedSymbol(AstNode::PrimaryKind, "primary"); return false; } (*yynode)->leftExpr = __node_14; while (yytoken == Token_STAR) { if (yytoken != Token_STAR) { expectedToken(yytoken, Token_STAR, "*"); return false; } yylex(); PrimaryAst *__node_15 = 0; if (!parsePrimary(&__node_15)) { expectedSymbol(AstNode::PrimaryKind, "primary"); return false; } (*yynode)->rightExpr = __node_15; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parsePrimary(PrimaryAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; (*yynode)->num = -1; (*yynode)->id = -1; if (yytoken == Token_NUMBER || yytoken == Token_IDENTIFIER) { if (yytoken == Token_NUMBER) { if (yytoken != Token_NUMBER) { expectedToken(yytoken, Token_NUMBER, "integer literal"); return false; } (*yynode)->num = tokenStream->index() - 1; yylex(); } else if (yytoken == Token_IDENTIFIER) { if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->id = tokenStream->index() - 1; yylex(); if (yytoken == Token_LPAREN) { if (yytoken != Token_LPAREN) { expectedToken(yytoken, Token_LPAREN, "("); return false; } yylex(); ExpressionAst *__node_16 = 0; if (!parseExpression(&__node_16)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->argumentSequence = snoc((*yynode)->argumentSequence, __node_16, memoryPool); while (yytoken == Token_COMMA) { if (yytoken != Token_COMMA) { expectedToken(yytoken, Token_COMMA, ","); return false; } yylex(); ExpressionAst *__node_17 = 0; if (!parseExpression(&__node_17)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->argumentSequence = snoc((*yynode)->argumentSequence, __node_17, memoryPool); } if (yytoken != Token_RPAREN) { expectedToken(yytoken, Token_RPAREN, ")"); return false; } yylex(); } else if (true /*epsilon*/) { } else { return false; } } else { return false; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseProgram(ProgramAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_FUNCTION || yytoken == Token_EOF) { while (yytoken == Token_FUNCTION) { FunctionDefinitionAst *__node_18 = 0; if (!parseFunctionDefinition(&__node_18)) { expectedSymbol(AstNode::FunctionDefinitionKind, "functionDefinition"); return false; } (*yynode)->funSequence = snoc((*yynode)->funSequence, __node_18, memoryPool); } if (Token_EOF != yytoken) { return false; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseReturnStatement(ReturnStatementAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_RETURN) { if (yytoken != Token_RETURN) { expectedToken(yytoken, Token_RETURN, "return"); return false; } yylex(); ExpressionAst *__node_19 = 0; if (!parseExpression(&__node_19)) { expectedSymbol(AstNode::ExpressionKind, "expression"); return false; } (*yynode)->expr = __node_19; if (yytoken != Token_SEMICOLON) { expectedToken(yytoken, Token_SEMICOLON, ";"); return false; } yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseStatement(StatementAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; if (yytoken == Token_IF || yytoken == Token_IDENTIFIER || yytoken == Token_RETURN || yytoken == Token_LBRACE) { if (yytoken == Token_IDENTIFIER) { AssignmentStatementAst *__node_20 = 0; if (!parseAssignmentStatement(&__node_20)) { expectedSymbol(AstNode::AssignmentStatementKind, "assignmentStatement"); return false; } (*yynode)->assignStmt = __node_20; } else if (yytoken == Token_IF) { IfStatementAst *__node_21 = 0; if (!parseIfStatement(&__node_21)) { expectedSymbol(AstNode::IfStatementKind, "ifStatement"); return false; } (*yynode)->ifStmt = __node_21; } else if (yytoken == Token_LBRACE) { BlockStatementAst *__node_22 = 0; if (!parseBlockStatement(&__node_22)) { expectedSymbol(AstNode::BlockStatementKind, "blockStatement"); return false; } (*yynode)->blockStmt = __node_22; } else if (yytoken == Token_RETURN) { ReturnStatementAst *__node_23 = 0; if (!parseReturnStatement(&__node_23)) { expectedSymbol(AstNode::ReturnStatementKind, "returnStatement"); return false; } (*yynode)->returnStmt = __node_23; } else { return false; } } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } bool Parser::parseVariable(VariableAst **yynode) { *yynode = create(); (*yynode)->startToken = tokenStream->index() - 1; (*yynode)->id = -1; if (yytoken == Token_IDENTIFIER) { if (yytoken != Token_IDENTIFIER) { expectedToken(yytoken, Token_IDENTIFIER, "identifier"); return false; } (*yynode)->id = tokenStream->index() - 1; yylex(); } else { return false; } (*yynode)->endToken = tokenStream->index() - 2; return true; } } // end of namespace fact diff --git a/examples/php/php.g b/examples/php/php.g index 20fe357..9f95732 100644 --- a/examples/php/php.g +++ b/examples/php/php.g @@ -1,1153 +1,1153 @@ %token_stream TokenStream ; -- %input_encoding "utf8" %input_encoding "ascii" %sequence_lexer %input_stream "KDevPG::QByteArrayIterator" %parser_declaration_header "QtCore/QDebug" %lexer_bits_header "QtCore/QDebug" %lexer_bits_header "algorithm" %lexer_declaration_header "QtCore/QStack" %lexer_declaration_header "utility" -- pair %lexerclass(private declaration) [: QStack > nowDocStack; Iterator::PlainIterator hereDocHeaderBegin, hereDocHederEnd; :] ------------------------------------------------------------ -- Enumeration types for additional AST members, -- in the global "Php" namespace ------------------------------------------------------------ %namespace [: class Lexer; enum ModifierFlags { ModifierPrivate = 1, ModifierPublic = 1 << 1, ModifierProtected = 1 << 2, ModifierStatic = 1 << 3, ModifierFinal = 1 << 4, ModifierAbstract = 1 << 5 }; enum ClassModifier { NormalClass, AbstractClass, FinalClass }; enum ScalarTypes { ScalarTypeInt, ScalarTypeFloat, ScalarTypeString }; enum CastType { CastInt, CastDouble, CastString, CastArray, CastObject, CastBool, CastUnset }; enum OperationType { OperationPlus = 1, OperationMinus, OperationConcat, OperationMul, OperationDiv, OperationMod, OperationAnd, OperationOr, OperationXor, OperationSl, OperationSr }; :] ------------------------------------------------------------ -- Ast Node class members ------------------------------------------------------------ %ast_extra_members [: //KDevelop::DUContext* ducontext; :] ------------------------------------------------------------ -- Parser class members ------------------------------------------------------------ %parserclass (public declaration) [: enum ProblemType { Error, Warning, Info }; void reportProblem( Parser::ProblemType type, const QString& message, int tokenOffset = -1 ); QString tokenText(qint64 begin, qint64 end); void setDebug(bool debug); enum InitialLexerState { HtmlState = 0, DefaultState = 1 }; :] %parserclass (private declaration) [: enum VarExpressionState { Normal, OnlyVariable, OnlyNewObject }; QString m_contents; bool m_debug; struct ParserState { VarExpressionState varExpressionState; bool varExpressionIsVariable; }; ParserState m_state; :] %parserclass (constructor) [: m_state.varExpressionState = Normal; m_state.varExpressionIsVariable = false; :] %lexerclass(constructor) [: :] -- keywords: %token ABSTRACT ("abstract"), BREAK ("break"), CASE ("case"), CATCH ("catch"), CLASS ("class"), CONST ("const"), CONTINUE ("continue"), DEFAULT ("default"), DO ("do"), ELSE ("else"), EXTENDS ("extends"), FINAL ("final"), FOR ("for"), IF ("if"), IMPLEMENTS ("implements"), INSTANCEOF ("instanceof"), INTERFACE ("interface"), NEW ("new"), PRIVATE ("private"), PROTECTED ("protected"), PUBLIC ("public"), RETURN ("return"), STATIC ("static"), SWITCH ("switch"), THROW ("throw"), TRY ("try"), WHILE ("while"), ECHO ("echo"), PRINT ("print"), CLONE ("clone"), EXIT ("exit"), ELSEIF ("elseif"), ENDIF ("endif"), ENDWHILE ("endwhile"), ENDFOR ("endfor"), FOREACH ("foreach"), ENDFOREACH ("endforeach"), DECLARE ("declare"), ENDDECLARE ("enddeclare"), AS ("as"), ENDSWITCH ("endswitch"), FUNCTION ("function"), USE ("use"), GLOBAL ("global"), VAR ("var "), UNSET ("unset"), ISSET ("isset"), EMPTY ("empty"), HALT_COMPILER ("halt compiler"), DOUBLE_ARROW ("=>"), LIST ("list"), ARRAY ("array"), CLASS_C ("__CLASS__"), METHOD_C ("__METHOD__"), FUNC_C ("__FUNCTION__"), LINE ("__LINE__"), FILE ("__FILE__"), COMMENT ("comment"), DOC_COMMENT ("doc comment"), PAAMAYIM_NEKUDOTAYIM ("::"), INCLUDE ("include"), INCLUDE_ONCE ("include_once"), EVAL ("eval"), REQUIRE ("require"), REQUIRE_ONCE ("require_once"), NAMESPACE ("namespace"), NAMESPACE_C("__NAMESPACE__"), USE("use"), GOTO ("goto") ; -- casts: %token INT_CAST ("int cast"), DOUBLE_CAST ("double cast"), STRING_CAST ("string cast"), ARRAY_CAST ("array cast"), OBJECT_CAST ("object cast"), BOOL_CAST ("bool cast"), UNSET_CAST ("unset cast") ; -- seperators: %token SEMICOLON (";"), DOUBLE_QUOTE ("\""), LBRACKET ("["), RBRACKET ("]"), LPAREN ("("), RPAREN (")"), LBRACE ("{"), RBRACE ("}"), COMMA (","), AT ("@"), CURLY_OPEN ("curly open"), -- { in "{$foo}"; not the same as LBRACE DOLLAR_OPEN_CURLY_BRACES ("${"), START_HEREDOC ("start heredoc"), END_HEREDOC ("end heredoc"), BACKTICK ("`"), BACKSLASH ("\\"), START_NOWDOC("start nowdoc"), END_NOWDOC("end nowdoc") ; -- operators: %token IS_EQUAL ("=="), IS_NOT_EQUAL ("!="), IS_IDENTICAL ("==="), IS_NOT_IDENTICAL ("!=="), IS_SMALLER ("<"), IS_GREATER (">"), IS_SMALLER_OR_EQUAL ("<="), IS_GREATER_OR_EQUAL (">="), BOOLEAN_OR ("||"), BOOLEAN_AND ("&&"), ASSIGN ("="), PLUS_ASSIGN ("+="), MINUS_ASSIGN ("-="), MUL_ASSIGN ("*="), DIV_ASSIGN ("/="), CONCAT_ASSIGN (".="), MOD_ASSIGN ("%="), AND_ASSIGN ("&="), OR_ASSIGN ("|="), XOR_ASSIGN ("^="), SL_ASSIGN ("<<="), SR_ASSIGN (">>="), OBJECT_OPERATOR ("->"), PLUS ("+"), MINUS("-"), CONCAT("."), INC ("++"), DEC ("--"), BANG ("!"), QUESTION ("?"), COLON (":"), BIT_AND ("&"), BIT_OR("|"), BIT_XOR ("^"), SL ("<<"), SR (">>"), MUL("*"), DIV("/"), MOD ("%"), TILDE ("~"), DOLLAR ("$"), LOGICAL_OR ("logical or"), LOGICAL_AND ("logical and"), LOGICAL_XOR ("logical xor") ; -- literals and identifiers: %token INLINE_HTML ("inline html"), WHITESPACE ("whitespace"), CONSTANT_ENCAPSED_STRING ("constant encapsed string"), VARIABLE ("variable"), ENCAPSED_AND_WHITESPACE ("encapsed and whitespace"), DNUMBER ("double number"), LNUMBER ("long number"), NUM_STRING ("num string"), STRING ("string"), STRING_VARNAME ("string varname") ; -- when in "${varname}" -- open/close tags %token OPEN_TAG (""), OPEN_TAG_WITH_ECHO (" " %error [: qDebug() << "error in php"; throw exception(); :] ; [{alphabetic}_][{alphabetic}{num}_]* -> identifier ; "<<<"{identifier}\n [: qDebug() << "start heredoc"; nowDocStack.push(make_pair(lxBEGIN_POS + 3, lxCURR_POS - 1)); :] START_HEREDOC; "<<<'"{identifier}"'"\n [: lxSET_RULE_SET(nowdoc); nowDocStack.push(make_pair(lxBEGIN_POS + 4, lxCURR_POS - 2)); :] START_NOWDOC; -- abstract ABSTRACT ; -- break BREAK ; -- case CASE ; -- catch CATCH ; -- class CLASS ; -- const CONST ; -- continue CONTINUE ; -- default DEFAULT ; -- do DO ; -- else ELSE ; -- extends EXTENDS ; -- final FINAL ; -- for FOR ; -- if IF ; -- implements IMPLEMENTS ; -- instanceof INSTANCEOF ; -- interface INTERFACE ; -- new NEW ; -- private PRIVATE ; -- protected PROTECTED ; -- public PUBLIC ; -- return RETURN ; -- static STATIC ; -- switch SWITCH ; -- throw THROW ; -- try TRY ; -- while WHILE ; echo ECHO ; -- print PRINT ; -- clone CLONE ; -- exit EXIT ; -- elseif ELSEIF ; -- endif ENDIF ; -- endwhile ENDWHILE ; -- endfor ENDFOR ; -- foreach FOREACH ; -- endforeach ENDFOREACH ; -- declare DECLARE ; -- enddeclare ENDDECLARE ; -- as AS ; -- endswitch ENDSWITCH ; -- function FUNCTION ; -- use USE ; -- global GLOBAL ; -- var VAR ; -- unset UNSET ; -- isset ISSET ; -- empty EMPTY ; -- __halt_compiler HALT_COMPILER ; -- "=>" DOUBLE_ARROW ; -- list LIST ; -- array ARRAY ; -- "__CLASS__" CLASS_C ; -- "__METHOD__" METHOD_C ; -- "__FUNCTION__" FUNC_C ; -- "__LINE__" LINE ; -- "__FILE__" FILE ; -- "::" PAAMAYIM_NEKUDOTAYIM ; -- include INCLUDE ; -- include_once INCLUDE_ONCE ; -- eval EVAL ; -- require REQUIRE ; -- require_once REQUIRE_ONCE ; -- namespace NAMESPACE ; -- "__NAMESPACE__" NAMESPACE_C ; -- use USE ; -- goto GOTO ; "/**"{white_space}(\.*^"*/")"*/" DOC_COMMENT ; "/*"(\.*^"*/")"*/"|"//"[.^\n]* COMMENT ; "?>" [: lxSET_RULE_SET(start) :] CLOSE_TAG ; -- "("{white_space}* -> bcast ; -- {white_space}*")" -> ecast ; -- {bcast}(int|integer){ecast} INT_CAST ; -- {bcast}(double|real|float){ecast} DOUBLE_CAST ; -- {bcast}(string|binary){ecast} STRING_CAST ; -- {bcast}"array"{ecast} ARRAY_CAST ; -- {bcast}"object"{ecast} OBJECT_CAST ; -- {bcast}(bool|boolean){ecast} BOOL_CAST ; -- {bcast}"unset"{ecast} UNSET_CAST ; -- "==" IS_EQUAL; -- "!=" IS_NOT_EQUAL; -- "===" IS_IDENTICAL; -- "!==" IS_NOT_IDENTICAL; -- "<" IS_SMALLER; -- ">" IS_GREATER; -- "<=" IS_SMALLER_OR_EQUAL; -- ">=" IS_GREATER_OR_EQUAL; -- "||" BOOLEAN_OR; -- "&&" BOOLEAN_AND; -- "=" ASSIGN; -- "+=" PLUS_ASSIGN; -- "-=" MINUS_ASSIGN; -- "*=" MUL_ASSIGN; -- "/=" DIV_ASSIGN; -- ".=" CONCAT_ASSIGN; -- "%=" MOD_ASSIGN; -- "&=" AND_ASSIGN; -- "|=" OR_ASSIGN; -- "^=" XOR_ASSIGN; -- "<<=" SL_ASSIGN; -- ">>=" SR_ASSIGN; -- "->" OBJECT_OPERATOR; -- "+" PLUS; -- "-" MINUS; -- "." CONCAT; -- "++" INC; -- "--" DEC; -- "!" BANG; -- "?" QUESTION; -- ":" COLON; -- "&" BIT_AND; -- "|" BIT_OR; -- "^" BIT_XOR; -- "<<" SL; -- ">>" SR; -- "*" MUL; -- "/" DIV; -- "%" MOD; -- "~" TILDE; -- "$" DOLLAR; -- "or" LOGICAL_OR; -- "and" LOGICAL_AND; -- "xor" LOGICAL_XOR; ";" SEMICOLON; "[" LBRACKET; "]" RBRACKET; "(" LPAREN; ")" RPAREN; "{" LBRACE; "}" RBRACE; "," COMMA; "@" AT; ("$"{identifier}) VARIABLE ; {identifier} STRING ; {white_space}+ ; -- WHITESPACE ; %lexer "heredoc" -> %enter [: qDebug() << "entering heredoc"; :] %fail [: qDebug() << "failed in heredoc"; throw exception(); :] -- "$"{identifier} "${"{identifier} [: qDebug() << "found opening"; lxNAMED_TOKEN(open, DOLLAR_OPEN_CURLY_BRACES) open.end = open.begin + 1; lxNAMED_TOKEN(varname, STRING_VARNAME) varname.begin += 2; lxDONE :] ; [.^\n]*. %ba("${") [: std::size_t topLength = nowDocStack.top().second - nowDocStack.top().first; if(lxLENGTH >= topLength && equal(nowDocStack.top().first, nowDocStack.top().second, lxBEGIN_POS)) { qDebug() << "heredoc match"; lxCURR_POS = lxBEGIN_POS + topLength; nowDocStack.pop(); lxRETURN(END_HEREDOC); } qDebug() << "heredoc line"; :] ENCAPSED_AND_WHITESPACE; ; %lexer "nowdoc" -> [.^\n]*\n [: std::size_t topLength = nowDocStack.top().second - nowDocStack.top().first; if(lxLENGTH >= topLength && equal(nowDocStack.top().first, nowDocStack.top().second, lxBEGIN_POS)) { lxCURR_POS = lxBEGIN_POS + topLength; nowDocStack.pop(); lxSET_RULE_SET(php); lxRETURN(END_NOWDOC); } qDebug() << "nowdoc line"; :] STRING; ; -- The actual grammar starts here. #statements=outerTopStatement* -> start ;; namespaceDeclaration=namespaceDeclarationStatement | statement=topStatement -> outerTopStatement ;; -- first/first conflict for FUNCTION (?[: (LA(1).kind == Token_FUNCTION && ((LA(2).kind == Token_BIT_AND && LA(3).kind == Token_LPAREN) || LA(2).kind == Token_LPAREN)) || LA(1).kind != Token_FUNCTION :] statement=statement ) | functionDeclaration=functionDeclarationStatement | classDeclaration=classDeclarationStatement | interfaceDeclaration=interfaceDeclarationStatement | HALT_COMPILER LPAREN RPAREN SEMICOLON -- Lexer stops allready -> topStatement ;; [: bool reported = false; while ( true ) { :] try/recover(#statements=topStatement)* [: if (yytoken != Token_RBRACE && yytoken != Token_EOF && yytoken != Token_CLOSE_TAG && yytoken != Token_ELSEIF && yytoken != Token_ELSE && yytoken != Token_ENDIF && yytoken != Token_ENDFOREACH && yytoken != Token_ENDFOR && yytoken != Token_ENDWHILE && yytoken != Token_ENDSWITCH && yytoken != Token_ENDDECLARE && yytoken != Token_CASE && yytoken != Token_DEFAULT) { if (!reported) { qint64 index = tokenStream->index() - 1; Token &token = tokenStream->at(index); QString tokenValue = token.kind != 0 ? tokenText(token.begin, token.end) : "EOF"; reportProblem(Error, QString("Unexpected token \"%1\".").arg(tokenValue)); reported = true; } yylex(); } else { break; } } :] -> innerStatementList ;; --Operator Precedence, from PHP Manual --left or --left xor --left and --right print --right = += -= *= /= .= %= &= |= ^= <<= >>= assignment --left ? : ternary --left || logical --left && logical --left | bitwise --left ^ bitwise --left & bitwise and references --non-associative == != === !== comparison --non-associative < <= > >= comparison --left << >> bitwise --left + - . arithmetic and string --left * / % arithmetic --non-associative ! ~ - (int) (float) (string) (array) (object) @ types --non-associative ++ -- increment/decrement --left [ array() --non-associative new new expression=logicalOrExpression -> expr ;; #expression=logicalXorExpression @ LOGICAL_OR -> logicalOrExpression ;; #expression=logicalAndExpression @ LOGICAL_XOR -> logicalXorExpression ;; #expression=printExpression @ LOGICAL_AND -> logicalAndExpression ;; (print=PRINT*) expression=assignmentExpression -> printExpression ;; -- leftside must me a variable, we check afterwards if it was a variable and -- if not we report an error 0 --needed for line below [: m_state.varExpressionIsVariable = false; :] --reset flag expression=conditionalExpression ( assignmentExpressionEqual=assignmentExpressionEqual | ( ( PLUS_ASSIGN [: (*yynode)->operation = OperationPlus; :] | MINUS_ASSIGN [: (*yynode)->operation = OperationMinus; :] | MUL_ASSIGN [: (*yynode)->operation = OperationMul; :] | DIV_ASSIGN [: (*yynode)->operation = OperationDiv; :] | CONCAT_ASSIGN [: (*yynode)->operation = OperationConcat; :] | MOD_ASSIGN [: (*yynode)->operation = OperationMod; :] | AND_ASSIGN [: (*yynode)->operation = OperationAnd; :] | OR_ASSIGN [: (*yynode)->operation = OperationOr; :] | XOR_ASSIGN [: (*yynode)->operation = OperationXor; :] | SL_ASSIGN [: (*yynode)->operation = OperationSl; :] | SR_ASSIGN [: (*yynode)->operation = OperationSr; :] ) assignmentExpressionCheckIfVariable assignmentExpression=assignmentExpression) | 0) -> assignmentExpression [ member variable operation: OperationType; ];; --=& is special: -- $foo =& $var; is allowed but not $foo =& 'static'; -- $foo =& new bar(); is allowed too but deprecated and reports a warning --we set a flag (varExpressionState) with that var_expression accepts only valid parts --this is done in such a strage way because we need the full expression to allow --things like $foo =& $bar || e(); ASSIGN assignmentExpressionCheckIfVariable --as in assignmentExpression (BIT_AND [: if (yytoken == Token_NEW) { reportProblem(Warning, "=& new foo() is deprecated", -2); m_state.varExpressionState = OnlyNewObject; } else { m_state.varExpressionState = OnlyVariable; }:] | 0) assignmentExpression=assignmentExpression [: m_state.varExpressionState = Normal; :] -> assignmentExpressionEqual ;; -- check if var_expression was a variable, if not report an error -- varExpressionIsVariable is set in var_expression 0 --to allow cpp-code [: if (!m_state.varExpressionIsVariable) { reportProblem(Error, "Left side is not a variable"); return false; } :] -> assignmentExpressionCheckIfVariable ;; expression=booleanOrExpression ( QUESTION (ifExpression=expr|0) COLON elseExpression=conditionalExpression | 0 ) -> conditionalExpression ;; #expression=booleanAndExpression @ BOOLEAN_OR -> booleanOrExpression ;; #expression=bitOrExpression @ BOOLEAN_AND -> booleanAndExpression ;; #expression=bitXorExpression @ BIT_OR -> bitOrExpression ;; #expression=bitAndExpression @ BIT_XOR -> bitXorExpression ;; #expression=equalityExpression @ BIT_AND -> bitAndExpression ;; expression=relationalExpression (#additionalExpression=equalityExpressionRest)* -> equalityExpression ;; ( IS_EQUAL | IS_NOT_EQUAL | IS_IDENTICAL | IS_NOT_IDENTICAL ) expression=relationalExpression -> equalityExpressionRest ;; expression=shiftExpression ( (#additionalExpression=relationalExpressionRest)+ --instanceof as in java.g (correct??) | INSTANCEOF instanceofType=classNameReference | 0 ) -> relationalExpression ;; ( IS_SMALLER | IS_GREATER | IS_SMALLER_OR_EQUAL | IS_GREATER_OR_EQUAL ) expression=shiftExpression -> relationalExpressionRest ;; expression=additiveExpression (#additionalExpression=shiftExpressionRest)* -> shiftExpression ;; ( SL | SR ) expression=additiveExpression -> shiftExpressionRest ;; expression=multiplicativeExpression (#additionalExpression=additiveExpressionRest)* -> additiveExpression ;; ( PLUS [: (*yynode)->operation = OperationPlus; :] | MINUS [: (*yynode)->operation = OperationMinus; :] | CONCAT [: (*yynode)->operation = OperationConcat; :] ) expression=multiplicativeExpression -> additiveExpressionRest [ member variable operation: OperationType; ];; expression=unaryExpression (#additionalExpression=multiplicativeExpressionRest)* -> multiplicativeExpression ;; ( MUL [: (*yynode)->operation = OperationMul; :] | DIV [: (*yynode)->operation = OperationDiv; :] | MOD [: (*yynode)->operation = OperationMod; :] ) expression=unaryExpression -> multiplicativeExpressionRest [ member variable operation: OperationType; ];; ( MINUS unaryExpression=unaryExpression | PLUS unaryExpression=unaryExpression | BANG unaryExpression=unaryExpression | TILDE unaryExpression=unaryExpression | INT_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastInt; :] | DOUBLE_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastDouble; :] | STRING_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastString; :] | ARRAY_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastArray; :] | OBJECT_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastObject; :] | BOOL_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastBool; :] | UNSET_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastUnset; :] | AT unaryExpression=unaryExpression | LIST LPAREN assignmentList=assignmentList RPAREN ASSIGN unaryExpression=unaryExpression | EXIT (LPAREN (expression=expr | 0) RPAREN | 0) | EVAL LPAREN expression=expr RPAREN | INCLUDE includeExpression=unaryExpression | INCLUDE_ONCE includeExpression=unaryExpression | REQUIRE includeExpression=unaryExpression | REQUIRE_ONCE includeExpression=unaryExpression | unaryExpressionNotPlusminus=unaryExpressionNotPlusminus ) -> unaryExpression [ member variable castType: CastType; ];; (#prefixOperator=postprefixOperator)* varExpression=varExpression (#postfixOperator=postprefixOperator)* -> unaryExpressionNotPlusminus ;; op=INC | op=DEC -> postprefixOperator ;; --first/first conflict - no problem because of ifs ?[: m_state.varExpressionState == OnlyVariable :] 0 [: m_state.varExpressionState = Normal; :] variable=variable | ?[: m_state.varExpressionState == OnlyNewObject :] 0 [: m_state.varExpressionState = Normal; :] newObject=varExpressionNewObject | varExpressionNormal=varExpressionNormal -> varExpression ;; LPAREN expression=expr RPAREN | BACKTICK encapsList=encapsList BACKTICK --try/rollback resolves conflict scalar vs. staticMember (foo::bar vs. foo::$bar) --varExpressionIsVariable flag is needed for assignmentExpression | try/rollback (variable=variable [: m_state.varExpressionIsVariable = true; :]) catch (scalar=scalar) | array=ARRAY LPAREN (#arrayValues=arrayPairValue -- break because array(1,) is allowed (solves FIRST/FOLLOW conflict) @ (COMMA [: if (yytoken == Token_RPAREN) { break; } :] ) | 0) RPAREN | ISSET LPAREN (#issetVariable=variable @ COMMA) RPAREN | EMPTY LPAREN emptyVarialbe=variable RPAREN | newObject=varExpressionNewObject | CLONE cloneCar=varExpressionNormal | closure=closure -> varExpressionNormal ;; -- http://wiki.php.net/rfc/closures FUNCTION (isRef=BIT_AND|0) LPAREN parameters=parameterList RPAREN ( USE LPAREN lexicalVars=lexicalVarList RPAREN | 0) LBRACE try/recover(functionBody=innerStatementList) RBRACE -> closure ;; (#lexicalVars=lexicalVar @ COMMA) | 0 [: reportProblem(Error, "Use list of closure must not be empty."); :] -> lexicalVarList ;; (isRef=BIT_AND | 0) variable=variableIdentifier -> lexicalVar ;; NEW className=classNameReference ctor=ctorArguments -> varExpressionNewObject ;; LPAREN parameterList=functionCallParameterList RPAREN | 0 -> ctorArguments ;; #parameters=functionCallParameterListElement @ COMMA | 0 -> functionCallParameterList ;; (BIT_AND variable=variable) | expr=expr -> functionCallParameterListElement ;; #element=assignmentListElement @COMMA -> assignmentList ;; variable=variable | LIST LPAREN assignmentList=assignmentList RPAREN | 0 -> assignmentListElement ;; expr=expr (DOUBLE_ARROW (exprValue=expr | BIT_AND varValue=variable) | 0) | BIT_AND variable=variable -> arrayPairValue ;; var=baseVariableWithFunctionCalls (#variableProperties=variableProperty*) -> variable ;; (OBJECT_OPERATOR|PAAMAYIM_NEKUDOTAYIM) ( ?[: LA(1).kind == Token_DOLLAR:] LBRACE variable=variable RBRACE | objectProperty=objectProperty ) (isFunctionCall=LPAREN parameterList=functionCallParameterList RPAREN | 0) -> variableProperty ;; --Conflict -- foo::$bar[0] (=baseVariable-staticMember) --vs.foo::$bar[0](); (=static function call) try/rollback (functionCall=functionCall) catch (baseVariable=baseVariable) -> baseVariableWithFunctionCalls ;; stringFunctionNameOrClass=namespacedIdentifier ( LPAREN stringParameterList=functionCallParameterList RPAREN | PAAMAYIM_NEKUDOTAYIM ( stringFunctionName=identifier LPAREN stringParameterList=functionCallParameterList RPAREN | varFunctionName=variableWithoutObjects LPAREN stringParameterList=functionCallParameterList RPAREN ) ) | varFunctionName=variableWithoutObjects LPAREN varParameterList=functionCallParameterList RPAREN -> functionCall ;; var=compoundVariableWithSimpleIndirectReference #offsetItems=dimListItem* | staticMember=staticMember -> baseVariable ;; variable=variableIdentifier | DOLLAR LBRACE expr=expr RBRACE -> compoundVariable ;; ( DOLLAR ( DOLLAR+ | 0 ) ( indirectVariable=variableIdentifier | LBRACE expr=expr RBRACE ) | variable=variableIdentifier ) -> compoundVariableWithSimpleIndirectReference ;; expr=expr | 0 -> dimOffset ;; className=namespacedIdentifier PAAMAYIM_NEKUDOTAYIM variable=variableWithoutObjects -> staticMember ;; LBRACE try/recover(statements=innerStatementList) RBRACE | IF LPAREN ifExpr=expr RPAREN ( COLON statements=innerStatementList newElseifList newElseSingle ENDIF semicolonOrCloseTag | ifStatement=statement elseifList=elseifList elseSingle=elseSingle ) | WHILE LPAREN whileExpr=expr RPAREN whileStatement=whileStatement | FOR LPAREN forExpr1=forExpr SEMICOLON forExpr2=forExpr SEMICOLON forExpr3=forExpr RPAREN forStatement=forStatement | SWITCH LPAREN swtichExpr=expr RPAREN switchCaseList=switchCaseList | FOREACH LPAREN ( -- allow $var as &$i and not expr() as &$i try/rollback(foreachVar=variable AS foreachVarAsVar=foreachVariable) catch(foreachExpr=expr AS foreachExprAsVar=variableIdentifier)) (DOUBLE_ARROW foreachVariable=foreachVariable | 0) RPAREN foreachStatement=foreachStatement | DECLARE LPAREN declareItem=declareItem @ COMMA RPAREN declareStatement | SEMICOLON -- empty statement | TRY LBRACE try/recover(statements=innerStatementList) RBRACE #catches=catchItem* | UNSET LPAREN #unsetVariables=variable @ COMMA RPAREN semicolonOrCloseTag -- fix first/follow with goto target | ( ?[: LA(1).kind != Token_STRING || LA(2).kind != Token_COLON :] expr=expr semicolonOrCloseTag ) | DO doStatement=statement WHILE LPAREN whileExpr=expr RPAREN semicolonOrCloseTag | BREAK (breakExpr=expr | 0) semicolonOrCloseTag | CONTINUE (continueExpr=expr | 0) semicolonOrCloseTag | RETURN (returnExpr=expr | 0) semicolonOrCloseTag | GLOBAL #globalVars=globalVar @ COMMA semicolonOrCloseTag | STATIC #staticVars=staticVar @ COMMA semicolonOrCloseTag | ECHO #echoExprs=expr @ COMMA semicolonOrCloseTag | THROW throwExpr=expr semicolonOrCloseTag -- throws error in zend parser, so ignored | USE use_filename semicolonOrCloseTag | CLOSE_TAG | OPEN_TAG | OPEN_TAG_WITH_ECHO expr=expr semicolonOrCloseTag | INLINE_HTML | CONST #consts=constantDeclaration @ COMMA SEMICOLON | USE #useNamespace=useNamespace @ COMMA SEMICOLON | GOTO gotoLabel=STRING SEMICOLON | gotoTarget=STRING COLON -> statement ;; identifier=namespacedIdentifier (AS aliasIdentifier=identifier | 0) -> useNamespace ;; identifier=identifier ASSIGN scalar=staticScalar -> constantDeclaration ;; SEMICOLON | CLOSE_TAG -> semicolonOrCloseTag ;; LBRACE (SEMICOLON | 0) try/recover(caseList=caseList) RBRACE | COLON (SEMICOLON | 0) caseList=caseList ENDSWITCH semicolonOrCloseTag -> switchCaseList ;; #caseItems=case_item* -> caseList ;; CASE expr=expr (COLON | SEMICOLON) statements=innerStatementList | def=DEFAULT (COLON | SEMICOLON) statements=innerStatementList -> case_item ;; CATCH LPAREN catchClass=identifier var=variableIdentifier RPAREN LBRACE try/recover(statements=innerStatementList) RBRACE -> catchItem ;; statement=statement | COLON statements=innerStatementList ENDDECLARE semicolonOrCloseTag -> declareStatement ;; STRING ASSIGN scalar=staticScalar -> declareItem ;; (BIT_AND | 0) variable=variableIdentifier -> foreachVariable ;; statement=statement | COLON statements=innerStatementList ENDFOREACH semicolonOrCloseTag -> foreachStatement ;; var=variableIdentifier (ASSIGN value=staticScalar | 0) -> staticVar ;; var=variableIdentifier | DOLLAR (dollarVar=variable | LBRACE expr=expr RBRACE) -> globalVar ;; #exprs=expr @ COMMA | 0 -> forExpr ;; statement=statement | COLON statements=innerStatementList ENDFOR semicolonOrCloseTag -> forStatement ;; statement=statement | COLON statements=innerStatementList ENDWHILE semicolonOrCloseTag -> whileStatement ;; --first/follow conflict; todo check if this is a problem #elseifListItem=elseifListItem* -> elseifList ;; ELSEIF LPAREN expr=expr RPAREN statement=statement -> elseifListItem ;; ELSE statement=statement | 0 -> elseSingle ;; #newElseifListItem=newelseifListItem* -> newElseifList ;; ELSEIF LPAREN expr=expr RPAREN COLON statements=innerStatementList -> newelseifListItem ;; ELSE COLON statements=innerStatementList | 0 -> newElseSingle ;; --TODO --resolve STRING vs. staticMember conflict -- ?[: LA(2).kind != Token_PAAMAYIM_NEKUDOTAYIM :] identifier=namespacedIdentifier | dynamicClassNameReference=dynamicClassNameReference -> classNameReference ;; baseVariable=baseVariable (OBJECT_OPERATOR objectProperty=objectProperty properties=dynamicClassNameVariableProperties | 0) -> dynamicClassNameReference ;; #properties=dynamicClassNameVariableProperty* -> dynamicClassNameVariableProperties ;; OBJECT_OPERATOR property=objectProperty -> dynamicClassNameVariableProperty ;; objectDimList=objectDimList | variableWithoutObjects=variableWithoutObjects -> objectProperty ;; variableName=variableName #offsetItems=dimListItem* -> objectDimList ;; variable=compoundVariableWithSimpleIndirectReference #offsetItems=dimListItem* -> variableWithoutObjects ;; LBRACKET dimOffset=dimOffset RBRACKET | LBRACE expr=expr RBRACE -> dimListItem ;; name=identifier | LBRACE expr=expr RBRACE -> variableName ;; commonScalar=commonScalar | constantOrClassConst=constantOrClassConst | varname=STRING_VARNAME | DOUBLE_QUOTE encapsList=encapsList DOUBLE_QUOTE | [: tokenStream->setRuleSet(TokenStream::State_heredoc); :] START_HEREDOC encapsList=encapsList [: tokenStream->setRuleSet(TokenStream::State_php); :] END_HEREDOC -> scalar ;; constant=namespacedIdentifier ( PAAMAYIM_NEKUDOTAYIM classConstant=identifier | 0 ) -> constantOrClassConst ;; #encaps=encaps* -> encapsList ;; var=encapsVar | value=ENCAPSED_AND_WHITESPACE -> encaps ;; -- first/first conflict resolved by LA(2) --(expr allows STRING_VARNAME too - but without [expr]) ( [: TokenStream::RuleSet lastRuleSet = tokenStream->ruleSet(); tokenStream->setRuleSet(TokenStream::State_php); :] DOLLAR_OPEN_CURLY_BRACES ( ?[: LA(2).kind == Token_LBRACKET:] STRING_VARNAME LBRACKET expr=expr RBRACKET | expr=expr ) [: tokenStream->setRuleSet(lastRuleSet); :] RBRACE | variable=variableIdentifier (OBJECT_OPERATOR propertyIdentifier=identifier | LBRACKET offset=encapsVarOffset RBRACKET | 0) | CURLY_OPEN expr=expr RBRACE) -> encapsVar ;; STRING | NUM_STRING | variableIdentifier -> encapsVarOffset ;; LNUMBER [: (*yynode)->scalarType = ScalarTypeInt; :] | DNUMBER [: (*yynode)->scalarType = ScalarTypeFloat; :] | string=CONSTANT_ENCAPSED_STRING [: (*yynode)->scalarType = ScalarTypeString; :] | LINE [: (*yynode)->scalarType = ScalarTypeInt; :] | FILE [: (*yynode)->scalarType = ScalarTypeString; :] | CLASS_C [: (*yynode)->scalarType = ScalarTypeString; :] | METHOD_C [: (*yynode)->scalarType = ScalarTypeString; :] | FUNC_C [: (*yynode)->scalarType = ScalarTypeString; :] | NAMESPACE_C [: (*yynode)->scalarType = ScalarTypeString; :] | START_NOWDOC STRING END_NOWDOC [: (*yynode)->scalarType = ScalarTypeString; :] -> commonScalar [ member variable scalarType: ScalarTypes; ] ;; FUNCTION (BIT_AND | 0) functionName=identifier LPAREN parameters=parameterList RPAREN LBRACE try/recover(functionBody=innerStatementList) RBRACE -> functionDeclarationStatement ;; (#parameters=parameter @ COMMA) | 0 -> parameterList ;; (parameterType=namespacedIdentifier | arrayType=ARRAY | 0) (isRef=BIT_AND | 0) variable=variableIdentifier (ASSIGN defaultValue=staticScalar | 0) -> parameter ;; value=commonScalar | constantOrClassConst=constantOrClassConst | PLUS plusValue=staticScalar | MINUS minusValue=staticScalar | array=ARRAY LPAREN (#arrayValues=staticArrayPairValue -- break because array(1,) is allowed @ (COMMA [: if (yytoken == Token_RPAREN) { break; } :] ) | 0) RPAREN -> staticScalar ;; #val1=staticScalar (DOUBLE_ARROW #val2=staticScalar | 0) -> staticArrayPairValue ;; (isGlobal=BACKSLASH | 0) #namespaceName=identifier+ @ BACKSLASH -> namespacedIdentifier ;; string=STRING -> identifier ;; variable=VARIABLE -> variableIdentifier ;; NAMESPACE #namespaceName=identifier* @ BACKSLASH ( -- the semicolon case needs at least one namespace identifier, the {...} case not... SEMICOLON [: if (!(*yynode)->namespaceNameSequence) { reportProblem(Error, "Missing namespace identifier.", -2); } :] | LBRACE try/recover(body=innerStatementList) RBRACE ) -> namespaceDeclarationStatement ;; INTERFACE interfaceName=identifier (EXTENDS extends=classImplements | 0) LBRACE try/recover(body=classBody) RBRACE -> interfaceDeclarationStatement ;; modifier=optionalClassModifier CLASS className=identifier (EXTENDS extends=classExtends | 0) (IMPLEMENTS implements=classImplements | 0) LBRACE body=classBody RBRACE -> classDeclarationStatement ;; identifier=namespacedIdentifier -> classExtends ;; #implements=namespacedIdentifier @ COMMA -> classImplements ;; -- error recovery, to understand it you probably have to look at the generated code ;-) [: bool reported = false; while ( true ) { :] try/recover(#classStatements=classStatement)* [: if (yytoken != Token_RBRACE && yytoken != Token_EOF && yytoken != Token_CLOSE_TAG) { if (!reported) { reportProblem(Error, "Unexpected token in class context."); reported = true; } yylex(); } else { break; } } :] RBRACE [: rewind(tokenStream->index() - 2); :] -> classBody ;; CONST #consts=constantDeclaration @ COMMA SEMICOLON | VAR variable=classVariableDeclaration SEMICOLON | modifiers=optionalModifiers ( variable=classVariableDeclaration SEMICOLON | FUNCTION (BIT_AND | 0) methodName=identifier LPAREN parameters=parameterList RPAREN methodBody=methodBody ) -> classStatement ;; SEMICOLON -- abstract method | LBRACE try/recover(statements=innerStatementList) RBRACE -> methodBody ;; #vars=classVariable @ COMMA -> classVariableDeclaration ;; variable=variableIdentifier (ASSIGN value=staticScalar | 0) -> classVariable ;; ( PUBLIC [: (*yynode)->modifiers |= ModifierPublic; :] | PROTECTED [: (*yynode)->modifiers |= ModifierProtected; :] | PRIVATE [: (*yynode)->modifiers |= ModifierPrivate; :] | STATIC [: (*yynode)->modifiers |= ModifierStatic; :] | ABSTRACT [: (*yynode)->modifiers |= ModifierAbstract; :] | FINAL [: (*yynode)->modifiers |= ModifierFinal; :] | 0 )* -> optionalModifiers[ member variable modifiers: unsigned int; ] ;; ( ABSTRACT [: (*yynode)->modifier = AbstractClass; :] | FINAL [: (*yynode)->modifier = FinalClass; :] | 0 ) -> optionalClassModifier[ member variable modifier: ClassModifier; ] ;; ----------------------------------------------------------------- -- Code segments copied to the implementation (.cpp) file. -- If existent, kdevelop-pg's current syntax requires this block -- to occur at the end of the file. ----------------------------------------------------------------- [: -#include +#include namespace Php { QString Parser::tokenText(qint64 begin, qint64 end) { return m_contents.mid(begin,end-begin+1); } void Parser::reportProblem( Parser::ProblemType type, const QString& message, int offset ) { if (type == Error) qDebug() << "** ERROR:" << message; else if (type == Warning) qDebug() << "** WARNING:" << message; else if (type == Info) qDebug() << "** Info:" << message; } // custom error recovery void Parser::expectedToken(int /*expected*/, qint64 /*where*/, const QString& name) { reportProblem( Parser::Error, QString("Expected token \"%1\"").arg(name)); } void Parser::expectedSymbol(int /*expectedSymbol*/, const QString& name) { qint64 line; qint64 col; qint64 index = tokenStream->index()-1; Token &token = tokenStream->at(index); qDebug() << "token starts at:" << token.begin; qDebug() << "index is:" << index; tokenStream->startPosition(index, &line, &col); QString tokenValue = tokenText(token.begin, token.end); qint64 eLine; qint64 eCol; tokenStream->endPosition(index, &eLine, &eCol); reportProblem( Parser::Error, QString("Expected symbol \"%1\" (current token: \"%2\" [%3] at %4:%5 - %6:%7)") .arg(name) .arg(token.kind != 0 ? tokenValue : "EOF") .arg(token.kind) .arg(line) .arg(col) .arg(eLine) .arg(eCol)); } void Parser::setDebug( bool debug ) { m_debug = debug; } Parser::ParserState *Parser::copyCurrentState() { ParserState *state = new ParserState(); state->varExpressionState = m_state.varExpressionState; state->varExpressionIsVariable = m_state.varExpressionIsVariable; return state; } void Parser::restoreState( Parser::ParserState* state) { m_state.varExpressionState = state->varExpressionState; m_state.varExpressionIsVariable = state->varExpressionIsVariable; } } // end of namespace Php :] -- kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on; auto-insert-doxygen on; mode KDevelop-PG[-Qt] diff --git a/include/kdev-pg-allocator.h b/include/kdev-pg-allocator.h index 7bf3b91..c7f77dd 100644 --- a/include/kdev-pg-allocator.h +++ b/include/kdev-pg-allocator.h @@ -1,152 +1,152 @@ /* This file is part of kdev-pg Copyright 2005, 2006 Roberto Raggi Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef KDEV_PG_ALLOCATOR_H #define KDEV_PG_ALLOCATOR_H #include #include #include -#include +#include namespace KDevPG { template class Allocator { public: typedef _Tp valueType; typedef _Tp* pointer; typedef const _Tp* constPointer; typedef _Tp& reference; typedef const _Tp& constReference; typedef ::std::size_t sizeType; typedef qint64 differenceType; static const sizeType maxBlockCount = sizeType( -1); Allocator() { sBlockIndex = sizeType(-1); sCurrentIndex = 0; sStorage = nullptr; sCurrentBlock = nullptr; } ~Allocator() { if (sStorage != nullptr) { for (sizeType index = 0; index <= sBlockIndex; ++index) delete[] sStorage[index]; std::free(sStorage); } } bool contains(void* ptr) { for(sizeType i = 0; i <= sBlockIndex; ++i) if(ptr >= (void*)(sStorage[i]) && ptr < (void*)(sStorage[i] + sBlockSize)) return true; return false; } pointer address(reference __val) { return &__val; } constPointer address(constReference __val) const { return &__val; } pointer allocate(sizeType __n, const void* = nullptr) { const sizeType bytes = __n * sizeof(_Tp); if (sCurrentBlock == nullptr || sBlockSize < sCurrentIndex + bytes) { ++sBlockIndex; sStorage = reinterpret_cast (std::realloc(sStorage, sizeof(char*) * (1 + sBlockIndex))); sCurrentBlock = sStorage[sBlockIndex] = reinterpret_cast (new char[sBlockSize]); std::memset(sCurrentBlock, 0, sBlockSize); sCurrentIndex = 0; } pointer p = reinterpret_cast (sCurrentBlock + sCurrentIndex); sCurrentIndex += bytes; return p; } void deallocate(pointer /*__p*/, sizeType /*__n*/) {} sizeType maxSize() const { return sizeType( -1) / sizeof(_Tp); } void contruct(pointer __p, constReference __val) { new (__p) _Tp(__val); } void destruct(pointer __p) { __p->~_Tp(); } private: template class Rebind { typedef Allocator<_Tp1> other; }; template Allocator(const Allocator<_Tp1> &/*__o*/) {} private: static const sizeType sBlockSize; sizeType sBlockIndex; sizeType sCurrentIndex; char *sCurrentBlock; char **sStorage; }; template const typename Allocator<_Tp>::sizeType Allocator<_Tp>::sBlockSize = 1 << 16; // 64K } #endif // KDEV_PG_ALLOCATOR_H diff --git a/include/kdev-pg-char-sets.h b/include/kdev-pg-char-sets.h index 2c103f2..d28a6ca 100644 --- a/include/kdev-pg-char-sets.h +++ b/include/kdev-pg-char-sets.h @@ -1,660 +1,660 @@ /* This file is part of kdev-pg-qt Copyright (C) 2010 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //krazy:excludeall=inline #ifndef KDEV_PG_CHAR_SETS #define KDEV_PG_CHAR_SETS #include #include #include #include #include #include #include using namespace std; -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include /** * @FILE * This file implements various iterator-classes providing character-set specific input streams. * Each iterator-class has these members: * @li Int: The type of the values returned by the stream * @li InputInt: Type of the values in the underlying representation * @li PlainIterator: InputInt*-like type used to reference underlying positions * @li next(): returns the next value and advances the stream position * @li hasNext(): checks if there are elements left * @li plain(): returns the PlainIterator for the next position * @li operator-(other): distance in the underlying representation between two of the iterators * @li begin: returns the PlainIterator at the beginning of the stream * @todo implement iterators for QIODevices, FILE and STL-streams, would need more abstraction: differentiate between input handling and decoding */ namespace KDevPG { enum CharEncoding { Ascii = 0, Latin1 = 1, Utf8 = 2, Utf16 = 3, Ucs2 = 4, Ucs4 = 5 }; template struct Codec2False { enum { value = false }; }; // use a bit more space than necessary, so we will be able to use ranges excluding the end template struct Codec2Int { typedef uchar Result; }; template<> struct Codec2Int { typedef quint16 Result; }; template<> struct Codec2Int { typedef quint16 Result; }; template<> struct Codec2Int { typedef quint32 Result; }; template<> struct Codec2Int { typedef quint32 Result; }; template<> struct Codec2Int { typedef quint32 Result; }; template struct Codec2Container { typedef QByteArray Result; }; template<> struct Codec2Container { typedef QVector Result; }; template<> struct Codec2Container { typedef QVector Result; }; template<> struct Codec2Container { typedef QVector Result; }; template struct Codec2Size { enum { value = 256 }; }; template<> struct Codec2Size { enum { value = 128 }; }; template<> struct Codec2Size { enum { value = 65536 }; // That is a really large table!! }; template<> struct Codec2Size { enum { value = 65536 }; // That is a really large table!! }; template<> struct Codec2Size { enum { value = 0x110000 }; // You should not do this!! }; template inline typename Codec2Container::Result qString2Codec(const QString& /*str*/) { static_assert(Codec2False::value, "Unknown codec"); } /// @todo check for invalid characters template<> inline QByteArray qString2Codec(const QString& str) { /// FIXME: in Qt5 there is no Ascii anymore, and in Qt4 it also was something different /// as it was configurable. In Russia, e.g. Ascii was something different than in Europe etc. pp... /// See: http://qt-project.org/doc/qt-4.8/qstring.html#toAscii /// All of this code here should probably be dropped and replaced by QTextCoded or similar return str.toLatin1(); } template<> inline QByteArray qString2Codec(const QString& str) { return str.toLatin1(); } template<> inline QByteArray qString2Codec(const QString& str) { return str.toUtf8(); } template<> inline QVector qString2Codec(const QString& str) { return str.toUcs4(); } template<> inline QVector qString2Codec(const QString& str) { QVector ret(str.size()); memcpy(&ret[0], str.utf16(), 2*str.size()); return ret; } template<> inline QVector qString2Codec(const QString& str) { QVector ret(str.size()); memcpy(&ret[0], str.utf16(), 2*str.size()); return ret; } class QStringIterator { QString::const_iterator _begin, iter, end; public: typedef quint16 Int; typedef quint16 InputInt; typedef QString::const_iterator PlainIterator; QStringIterator(const QString& str) : _begin(str.begin()), iter(str.begin()), end(str.end()) { } quint16 next() { return iter++->unicode(); } bool hasNext() { return iter != end; } ptrdiff_t operator-(const QStringIterator& other) const { return iter - other.iter; } PlainIterator plain() { return iter; } PlainIterator begin() { return _begin; } }; template class ByteStringIterator { typename String::const_iterator _begin, iter, end; public: typedef uchar Int; typedef uchar InputInt; typedef typename String::const_iterator PlainIterator; ByteStringIterator(const String& str) : _begin(str.begin()), iter(str.begin()), end(str.end()) { } uchar next() { return *iter++; } bool hasNext() { return iter != end; } ptrdiff_t operator-(const ByteStringIterator& other) const { return iter - other.iter; } PlainIterator& plain() { return iter; } PlainIterator& begin() { return _begin; } }; typedef ByteStringIterator QByteArrayIterator; typedef ByteStringIterator StdStringIterator; class QUtf16ToUcs4Iterator { union { QChar const *ptr; quint16 const *raw; }; quint16 const *_begin, *end; public: typedef quint32 Int; typedef quint16 InputInt; typedef InputInt const* PlainIterator; QUtf16ToUcs4Iterator(const QString& str) : raw(str.utf16()), _begin(str.utf16()), end(raw + str.size()) { } quint32 next() { quint32 ret = ptr->unicode(); if(QChar::isHighSurrogate(*raw)) ret = QChar::surrogateToUcs4(ret, *(++raw)); ++ptr; return ret; } bool hasNext() { return raw != end; } ptrdiff_t operator-(const QUtf16ToUcs4Iterator& other) const { return ptr - other.ptr; } PlainIterator& plain() { return raw; } PlainIterator& begin() { return _begin; } }; template class Utf8ToUcs4Iterator { public: typedef typename String::const_iterator PlainIterator; private: PlainIterator _begin, ptr, end; public: typedef quint32 Int; typedef uchar InputInt; Utf8ToUcs4Iterator(const String& str) : _begin(str.begin()), ptr(_begin), end(ptr + str.size()) { } PlainIterator& plain() { return ptr; } quint32 next() { /* Algorithm: Start: case chr < 128 use it directly case (chr & 0xe0) == 0xc0 (chr & 0x1f) -> add next case (chr & 0xf0) == 0xe0 (chr & 0x0f) -> add next two case (chr & 0xf8) == 0xf0 (chr & 0x07) -> add next three default invalid Add: condition: (next & 0xc0) == 0x80 ret = (ret << 6) | (nextChr & 0x3f) QChar::isUnicodeNonCharacter -> invalid */ while(true) { retry: uchar chr = *ptr; if(chr < 128) { ++ptr; return chr; } quint32 ret; if((chr & 0xe0) == 0xc0) { ret = ((chr & 0x1f) << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf0) == 0xe0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf8) == 0xf0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else { ++ptr; goto retry; } ++ptr; if((ret & 0xfffe) != 0xfffe && (ret - 0xfdd0U) > 15) return ret; // ignore the error, jump back :-) } } bool hasNext() { return ptr != end; } ptrdiff_t operator-(const String& other) const { return ptr - other.ptr; } PlainIterator& begin() { return _begin; } }; typedef Utf8ToUcs4Iterator QUtf8ToUcs4Iterator; typedef Utf8ToUcs4Iterator StdStringUtf8ToUcs4Iterator; class QUtf8ToUcs2Iterator { uchar const *_begin, *ptr, *end; public: typedef quint16 Int; typedef uchar InputInt; typedef InputInt const* PlainIterator; QUtf8ToUcs2Iterator(const QByteArray& qba) : _begin(reinterpret_cast(qba.data())), ptr(_begin), end(ptr + qba.size()) { } PlainIterator& plain() { return ptr; } quint16 next() { while(true) { retry: uchar chr = *ptr; if(chr < 128) { ++ptr; return chr; } quint32 ret; if((chr & 0xe0) == 0xc0) { ret = ((chr & 0x1f) << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf0) == 0xe0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf8) == 0xf0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else { ++ptr; goto retry; } ++ptr; if(ret <= 0xffff && (ret & 0xfffe) != 0xfffe && (ret - 0xfdd0U) > 15) return ret; // ignore the error, jump back :-) } } bool hasNext() { return ptr != end; } ptrdiff_t operator-(const QUtf8ToUcs2Iterator& other) const { return ptr - other.ptr; } PlainIterator& begin() { return _begin; } }; class QUtf8ToUtf16Iterator { uchar const *_begin, *ptr, *end; quint16 surrogate; public: typedef quint16 Int; typedef uchar InputInt; typedef InputInt const* PlainIterator; QUtf8ToUtf16Iterator(const QByteArray& qba) : _begin(reinterpret_cast(qba.data())), ptr(_begin), end(ptr + qba.size()), surrogate(0) { } PlainIterator& plain() { return ptr; } quint16 next() { if(surrogate != 0) { Int tmp = surrogate; surrogate = 0; return tmp; } while(true) { retry: uchar chr = *ptr; if(chr < 128) { ++ptr; return chr; } quint32 ret; if((chr & 0xe0) == 0xc0) { ret = ((chr & 0x1f) << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf0) == 0xe0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else if((chr & 0xf8) == 0xf0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } else { ++ptr; goto retry; } ++ptr; if(ret <= 0xffff) { if((ret & 0xfffe) != 0xfffe && (ret - 0xfdd0U) > 15) return ret; // ignoe the error ;) } else { surrogate = QChar::lowSurrogate(ret); return QChar::highSurrogate(ret); } } } bool hasNext() { return ptr != end; } ptrdiff_t operator-(const QUtf8ToUtf16Iterator& other) const { return ptr - other.ptr; } PlainIterator& begin() { return _begin; } }; class QUtf8ToAsciiIterator { uchar const *_begin, *ptr, *end; public: typedef uchar Int; typedef uchar InputInt; typedef InputInt const* PlainIterator; QUtf8ToAsciiIterator(const QByteArray& qba) : _begin(reinterpret_cast(qba.data())), ptr(_begin), end(ptr + qba.size()) { } PlainIterator& plain() { return ptr; } Int next() { while(true) { uchar chr = *ptr; if(chr < 128) { ++ptr; return chr; } quint32 ret; if((chr & 0xe0) == 0xc0) { ret = ((chr & 0x1f) << 6) | ((*++ptr) & 0x3f); } if((chr & 0xf0) == 0xe0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } if((chr & 0xf8) == 0xf0) { ret = ((chr & 0x0f) << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); ret = (ret << 6) | ((*++ptr) & 0x3f); } ++ptr; // ignore the error, jump back :-) // TODO: error handling? } } bool hasNext() { return ptr != end; } ptrdiff_t operator-(const QUtf8ToAsciiIterator& other) const { return ptr - other.ptr; } PlainIterator& begin() { return _begin; } }; template struct Codec2FromUtf8Iterator { typedef QByteArrayIterator Result; }; template<> struct Codec2FromUtf8Iterator { typedef QUtf8ToAsciiIterator Result; }; template<> struct Codec2FromUtf8Iterator { typedef QUtf8ToUcs2Iterator Result; }; template<> struct Codec2FromUtf8Iterator { typedef QUtf8ToUtf16Iterator Result; }; template<> struct Codec2FromUtf8Iterator { typedef QUtf8ToUcs4Iterator Result; }; } #endif diff --git a/include/kdev-pg-location-table.h b/include/kdev-pg-location-table.h index c176493..13eedbe 100644 --- a/include/kdev-pg-location-table.h +++ b/include/kdev-pg-location-table.h @@ -1,138 +1,137 @@ /* This file is part of kdev-pg Copyright 2002-2006 Roberto Raggi Copyright 2009 Milian Wolff Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ //krazy:excludeall=inline #ifndef KDEV_PG_LOCATION_TABLE_H #define KDEV_PG_LOCATION_TABLE_H -#include - -#include // krazy:exclude=includes +#include +#include namespace KDevPG { class LocationTable { public: inline LocationTable(qint64 size = 1024) : lines(nullptr), lineCount(0), currentLine(0), lastLine(0) { resize(size); lines[currentLine++] = 0; } inline ~LocationTable() { free(lines); } inline qint64 size() const { return lineCount; } void resize(qint64 size) { Q_ASSERT(size > 0); lines = (qint64*) ::realloc(lines, sizeof(qint64) * size); lineCount = size; } /** * Returns the \a line and \a column of the given \a offset in this table. */ void positionAt(qint64 offset, qint64 *line, qint64 *column) const { if ( offset < 0 ) { // invalid offset *line = -1; *column = -1; return; } else if ( offset > lines[currentLine - 1] ) { // overflow *line = currentLine - 1; *column = offset - lines[currentLine - 1]; return; } qint64 i = -1; // search relative to last line (next line and the one after that) if ( lastLine + 1 < currentLine && lines[lastLine] <= offset ) { if ( lines[lastLine + 1] > offset ) { // last matched line matches again i = lastLine; } else if ( lastLine + 2 < currentLine && lines[lastLine + 2] > offset ) { // next line relative to last matched matches i = lastLine + 1; } } if ( i == -1 ) { // fallback to binary search qint64 *it = std::lower_bound(lines, lines + currentLine, offset); Q_ASSERT(it != lines + currentLine); if (*it != offset) { --it; } *line = it - lines; *column = offset - *it; } else { *line = i; *column = offset - lines[i]; } lastLine = *line; } /** * Marks an \a offset as the character before the first one in the next line. * The positionAt() function relies on newline() being called properly. */ inline void newline(qint64 offset) { if (currentLine == lineCount) resize(currentLine * 2); lines[currentLine++] = offset+1; } inline qint64 &operator[](int index) { return lines[index]; } protected: /// An array of input buffer offsets qint64 *lines; /// The size of the allocated array qint64 lineCount; /// The index to the next index in the lines array qint64 currentLine; /// Last line as found by positionAt mutable qint64 lastLine; private: LocationTable(LocationTable const &other); void operator=(LocationTable const &other); }; } #endif // KDEV_PG_LOCATION_TABLE_H diff --git a/include/kdev-pg-memory-pool.h b/include/kdev-pg-memory-pool.h index 132c1ea..c897b3f 100644 --- a/include/kdev-pg-memory-pool.h +++ b/include/kdev-pg-memory-pool.h @@ -1,106 +1,106 @@ /* This file is part of kdev-pg Copyright 2005, 2006 Roberto Raggi Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ //krazy:excludeall=inline #ifndef KDEV_PG_MEMORY_POOL #define KDEV_PG_MEMORY_POOL -#include +#include #include #include namespace KDevPG { class BlockType { public: qint64 blockSize; BlockType *chain; char *data; char *ptr; char *end; inline void init(int block_size = 256) { blockSize = block_size; chain = nullptr; data = (char*) malloc(blockSize); ptr = data; end = data + block_size; } inline void init0(int block_size = 256) { init(block_size); memset(data, '\0', block_size); } inline void destroy() { if (chain) { chain->destroy(); free(chain); } free(data); } inline void *allocate(size_t size, BlockType **right_most) { if (end < ptr + size) { // assert( size < block_size ); if (!chain) { chain = (BlockType*) malloc(sizeof(BlockType)); chain->init0(blockSize << 2); } return chain->allocate(size, right_most); } char *r = ptr; ptr += size; if (right_most) *right_most = this; return r; } }; class MemoryPool { public: BlockType blk; BlockType *rightMost; inline MemoryPool() { blk.init0(); rightMost = &blk; } inline ~MemoryPool() { blk.destroy(); } inline void *allocate(size_t size) { return rightMost->allocate(size, &rightMost); } }; } #endif diff --git a/kdev-pg/kdev-pg-ast-gen.cpp b/kdev-pg/kdev-pg-ast-gen.cpp index b646a59..3645d46 100644 --- a/kdev-pg/kdev-pg-ast-gen.cpp +++ b/kdev-pg/kdev-pg-ast-gen.cpp @@ -1,310 +1,310 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-ast-gen.h" #include "kdev-pg-code-gen.h" #include "kdev-pg.h" -#include +#include namespace KDevPG { void GenerateAst::operator()() { out << globalSystem.namespaceCode << endl; out << "struct " << globalSystem.exportMacro << " AstNode"; out << "{" << endl << "enum AstNodeKind {" << endl; int node_id = 1000; for (QMap::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it) { Model::SymbolItem *sym = (*it); if(isOperatorSymbol(sym)) { out << "Prefix" << sym->mCapitalizedName << "Kind" << " = " << node_id << "," << endl; ++node_id; out << "Postfix" << sym->mCapitalizedName << "Kind" << " = " << node_id << "," << endl; ++node_id; out << "Binary" << sym->mCapitalizedName << "Kind" << " = " << node_id << "," << endl; ++node_id; out << "Ternary" << sym->mCapitalizedName << "Kind" << " = " << node_id << "," << endl; ++node_id; } out << sym->mCapitalizedName << "Kind" << " = " << node_id << "," << endl; ++node_id; } out << "AST_NODE_KIND_COUNT" << endl << "};" << endl << endl << "int kind;" << endl << "qint64 startToken;" << endl << "qint64 endToken;" << endl << globalSystem.astCode << endl << "};" << endl << endl; GenerateAstRule gen(out); for( World::SymbolSet::const_iterator it = globalSystem.symbols.constBegin(); it != globalSystem.symbols.constEnd(); ++it ) { gen(*it); } gen.mFirstTime = false; while(true) { int oldSize = gen.mToGenerate.size(); for(auto i = gen.mToGenerate.begin(); i != gen.mToGenerate.end(); ) { auto next = i; ++next; gen(*i); i = next; } if(gen.mToGenerate.size() == oldSize) break; } gen.mForce = true; for(auto i = gen.mToGenerate.begin(); i != gen.mToGenerate.end(); ) { auto next = i; ++next; gen(*i); i = next; } out << endl; } void GenerateAstRule::operator()(Model::SymbolItem *sym) { if(!mForce) { QString base = globalSystem.astBaseClasses.value(sym->mName, ""); if(!base.isEmpty() && !mGenerated.contains(base)) { if(mFirstTime) mToGenerate.insert(sym); return; } } if(!mFirstTime) mToGenerate.remove(sym); mNames.clear(); mInAlternative = false; mInCons = false; World::Environment::iterator it = globalSystem.env.find(sym); while (it != globalSystem.env.end()) { Model::EvolveItem *e = *it; if (it.key() != sym) break; ++it; visitNode(e); } } void GenerateAstRule::visitEvolve(Model::EvolveItem *node) { Model::SymbolItem *sym = node->mSymbol; if (node->mItem->kind == Model::OperatorItem::NodeKind) { out << "struct " << globalSystem.exportMacro << " " << sym->mCapitalizedName << "Ast: public " << globalSystem.astBaseClasses.value(sym->mName, "AstNode") << "{ enum { KIND = " << sym->mCapitalizedName << "Kind }; };" << endl << endl; #define O(thestr) \ out << "struct " << globalSystem.exportMacro << thestr << sym->mCapitalizedName << "Ast: public " \ << sym->mCapitalizedName << "Ast" \ << " {" << endl \ << "enum { KIND =" << thestr << sym->mCapitalizedName << "Kind };" << endl \ << "AstNode *first;" << endl \ << thestr << sym->mCapitalizedName << "Ast(" \ << ")" << endl \ << "{\n}" << endl \ << thestr << sym->mCapitalizedName << "Ast(" \ << "AstNode *first)" << endl \ << ": first(first)" << endl \ << "{\n}" << endl;\ mGenerated.insert(thestr); O(" Prefix") DefaultVisitor::visitEvolve(node); out << "};" << endl << endl; O(" Postfix") DefaultVisitor::visitEvolve(node); out << "};" << endl << endl; #undef O out << "struct " << globalSystem.exportMacro << " Binary" << sym->mCapitalizedName << "Ast: public " << sym->mCapitalizedName << "Ast" << " {" << endl << "enum { KIND = Binary" << sym->mCapitalizedName << "Kind };" << endl << "AstNode *first;" << endl << "AstNode *second;" << endl << "Binary" << sym->mCapitalizedName << "Ast(" << "AstNode *first)" << endl << ": first(first)" << endl << "{\n}" << endl; DefaultVisitor::visitEvolve(node); out << "};" << endl << endl; out << "struct " << globalSystem.exportMacro << " Ternary" << sym->mCapitalizedName << "Ast: public " << sym->mCapitalizedName << "Ast" << " {" << endl << "enum { KIND = Ternary" << sym->mCapitalizedName << "Kind };" << endl << "AstNode *first;" << endl << "AstNode *second;" << endl << "AstNode *third;" << endl << "Ternary" << sym->mCapitalizedName << "Ast(" << "AstNode *first)" << endl << ": first(first)" << endl << "{\n}" << endl; DefaultVisitor::visitEvolve(node); out << "};" << endl << endl; } else { out << "struct " << globalSystem.exportMacro << " " << sym->mCapitalizedName << "Ast: public " << globalSystem.astBaseClasses.value(sym->mName, "AstNode") << " {" << endl << "enum { KIND = " << sym->mCapitalizedName << "Kind };" << endl << endl; DefaultVisitor::visitEvolve(node); out << "};" << endl << endl; } } void GenerateAstRule::visitVariableDeclaration(Model::VariableDeclarationItem *node) { GenerateVariableDeclaration gen_var_decl(out); if (node->mStorageType != Model::VariableDeclarationItem::StorageTemporary && mNames.find(node->mName) == mNames.end()) { gen_var_decl(node); out << ";" << endl; mNames.insert(node->mName); } DefaultVisitor::visitVariableDeclaration(node); } void GenerateAstRule::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) { KDevPG::DefaultVisitor::visitEvolve(globalSystem.searchRule(node->mSymbol)); } void GenerateAstRule::visitAlternative(Model::AlternativeItem *node) { bool in_alternative = switchAlternative(true); #if defined(AST_OPT_BRANCH) if (!in_alternative) { out << "union" << endl << "{" << endl << "AstNode *__nodeCast;" << endl << "qint64 __token_cast;" << endl << endl; } #endif DefaultVisitor::visitAlternative(node); #if defined(AST_OPT_BRANCH) if (!in_alternative) out << "}; // union" << endl; #endif switchAlternative(in_alternative); } void GenerateAstRule::visitCons(Model::ConsItem *node) { bool in_cons = switchCons(true); #if defined(AST_OPT_BRANCH) if (!in_cons) { out << "struct" << endl << "{" << endl; } #endif DefaultVisitor::visitCons(node); #if defined(AST_OPT_BRANCH) if (!in_cons) { out << "}; // struct" << endl; mNames.clear(); } #endif switchCons(in_cons); } bool GenerateAstRule::switchAlternative(bool alt) { bool old = mInAlternative; mInAlternative = alt; return old; } bool GenerateAstRule::switchCons(bool c) { bool old = mInCons; mInCons = c; return old; } void GenerateAstFwd::operator()() { out << "struct " << " AstNode;"; for (QMap::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it) { Model::SymbolItem *sym = *it; #define O(name) out << "struct " << name << "Ast;" << endl; O(sym->mCapitalizedName) if(isOperatorSymbol(sym)) { O("Prefix" + sym->mCapitalizedName) O("Postfix" + sym->mCapitalizedName) O("Binary" + sym->mCapitalizedName) O("Ternary" + sym->mCapitalizedName) } #undef O } } } diff --git a/kdev-pg/kdev-pg-ast-gen.h b/kdev-pg/kdev-pg-ast-gen.h index 2876e9c..3cd58c8 100644 --- a/kdev-pg/kdev-pg-ast-gen.h +++ b/kdev-pg/kdev-pg-ast-gen.h @@ -1,88 +1,88 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_AST_GEN_H #define KDEV_PG_AST_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace KDevPG { class GenerateAst { public: QTextStream& out; public: GenerateAst(QTextStream& o): out(o) {} void operator()(); }; class GenerateAstRule: protected DefaultVisitor { public: QTextStream& out; QSet mNames; QSet mGenerated; QSet mToGenerate; bool mInAlternative; bool mInCons; bool mForce; bool mFirstTime; public: GenerateAstRule(QTextStream& o): out(o), mForce(false), mFirstTime(true) {} void operator()(Model::SymbolItem *sym); protected: void visitAlternative(Model::AlternativeItem *node) override; void visitVariableDeclaration(Model::VariableDeclarationItem *node) override; void visitCons(Model::ConsItem *node) override; void visitEvolve(Model::EvolveItem *node) override; void visitInlinedNonTerminal(Model::InlinedNonTerminalItem *node) override; bool switchAlternative(bool alt); bool switchCons(bool c); }; class GenerateAstFwd { public: QTextStream& out; public: GenerateAstFwd(QTextStream& o): out(o) {} void operator()(); }; } #endif // KDEV_PG_AST_GEN_H diff --git a/kdev-pg/kdev-pg-ast.h b/kdev-pg/kdev-pg-ast.h index b79c201..3193634 100644 --- a/kdev-pg/kdev-pg-ast.h +++ b/kdev-pg/kdev-pg-ast.h @@ -1,385 +1,385 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2010 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_AST_H #define KDEV_PG_AST_H #include "kdev-pg-allocator.h" #include "kdev-pg-memory-pool.h" #include #include using std::vector; using std::pair; using std::make_pair; -#include +#include -#include +#include #define PG_NODE(k) \ enum { NodeKind = NodeKind##k }; namespace KDevPG { // the kdev-pg calculus namespace Model { enum NodeKind { NodeKindItem = 0, NodeKindZero = 1, NodeKindPlus = 2, NodeKindStar = 3, NodeKindSymbol = 4, NodeKindAction = 5, NodeKindAlternative = 6, NodeKindCons = 7, NodeKindEvolve = 8, NodeKindTryCatch = 9, NodeKindAlias = 10, NodeKindTerminal = 11, NodeKindNonTerminal = 12, NodeKindAnnotation = 13, NodeKindCondition = 14, NodeKindVariableDeclaration = 15, NodeKindOperator = 16, NodeKindInlinedNonTerminal = 17, NodeKindLast }; class Node { public: PG_NODE(Item) int kind; }; class ZeroItem: public Node { public: PG_NODE(Zero) }; class PlusItem: public Node { public: PG_NODE(Plus) Node *mItem; }; class StarItem: public Node { public: PG_NODE(Star) Node *mItem; }; class SymbolItem: public Node { public: PG_NODE(Symbol) QString mName; QString mCapitalizedName; }; class ActionItem: public Node { public: PG_NODE(Action) Node *mItem; QString mCode; }; class AlternativeItem: public Node { public: PG_NODE(Alternative) Node *mLeft; Node *mRight; }; class ConsItem: public Node { public: PG_NODE(Cons) Node *mLeft; Node *mRight; }; class TryCatchItem: public Node { public: PG_NODE(TryCatch) Node *mTryItem; Node *mCatchItem; // contains 0 for "catch(recover)" bool mUnsafe; }; class AliasItem: public Node { public: PG_NODE(Alias) QString mCode; SymbolItem *mSymbol; }; class InlinedNonTerminalItem: public Node { public: PG_NODE(InlinedNonTerminal) SymbolItem *mSymbol; }; class TerminalItem: public Node { public: PG_NODE(Terminal) QString mName; QString mDescription; }; class NonTerminalItem: public Node { public: PG_NODE(NonTerminal) SymbolItem *mSymbol; QString mArguments; }; class Operator { public: Node *mTok; QString mCond, mCode; }; class OperatorItem : public Node { public: PG_NODE(Operator) struct TernDescription { Operator first, second; QString left; QString priority; }; struct BinDescription { Operator op; QString left; QString priority; }; struct UnaryDescription { Operator op; QString priority; }; struct ParenDescription { Operator first, second; }; QString mName; NonTerminalItem *mBase; vector< ParenDescription > mParen; vector< TernDescription > mTern; vector< BinDescription > mBin, mPost; vector< UnaryDescription > mPre; inline void pushParen(const Operator& op1, const Operator& op2) { ParenDescription d; d.first = op1; d.second = op2; mParen.push_back(d); } inline void pushPre(const Operator& op, const QString& priority) { UnaryDescription d; d.op = op; d.priority = priority; mPre.push_back(d); } inline void pushPost(const Operator& op, const QString& left, const QString& priority) { BinDescription d; d.op = op; d.priority = priority; d.left = left; mPost.push_back(d); } inline void pushBin(const Operator& op, const QString& left, const QString& priority) { BinDescription d; d.op = op; d.left = left; d.priority = priority; mBin.push_back(d); } inline void pushTern(const Operator& op1, const Operator& op2, const QString& left, const QString& priority) { TernDescription d; d.first = op1; d.second = op2; d.left = left; d.priority = priority; mTern.push_back(d); } }; class VariableDeclarationItem: public Node { public: PG_NODE(VariableDeclaration) enum DeclarationType { DeclarationArgument, DeclarationLocal }; enum StorageType { StorageAstMember, StorageTemporary }; enum VariableType { TypeNode, TypeToken, TypeVariable }; QString mType; QString mCapitalizedType; QString mName; DeclarationType mDeclarationType; StorageType mStorageType; VariableType mVariableType; bool mIsSequence; VariableDeclarationItem *mNext; }; class AnnotationItem: public Node { public: PG_NODE(Annotation) Node *mItem; VariableDeclarationItem *mDeclaration; }; class ConditionItem: public Node { public: PG_NODE(Condition) QString mCode; Node *mItem; }; class EvolveItem: public Node { public: PG_NODE(Evolve) Node *mItem; SymbolItem *mSymbol; VariableDeclarationItem *mDeclarations; QString mCode; }; } // namespace model // configuration stuff outside the model namespace Settings { enum NodeKind { NodeKindMember = 30, NodeKindLast }; class MemberItem: public Model::Node { public: PG_NODE(Member) enum MemberKind { PublicDeclaration = 1, ProtectedDeclaration = 2, PrivateDeclaration = 4, ConstructorCode = 8, DestructorCode = 16 }; MemberKind mMemberKind; QString mCode; }; } // namespace settings template struct StripPtr { typedef T Result; }; template struct StripPtr { typedef T Result; }; template _Tp nodeCast(Model::Node *item) { if (StripPtr<_Tp>::Result::NodeKind == item->kind) return static_cast<_Tp>(item); return nullptr; } extern KDevPG::Allocator globalMemoryPool; template _Tp *createNode() { _Tp *node = new (globalMemoryPool.allocate(sizeof(_Tp)))_Tp(); node->kind = _Tp::NodeKind; return node; } } #endif // KDEV_PG_AST_H diff --git a/kdev-pg/kdev-pg-beautifier.cpp b/kdev-pg/kdev-pg-beautifier.cpp index e56bd0c..9799664 100644 --- a/kdev-pg/kdev-pg-beautifier.cpp +++ b/kdev-pg/kdev-pg-beautifier.cpp @@ -1,94 +1,94 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-beautifier.h" -#include -#include +#include +#include namespace KDevPG { IteratorQTextStream::IteratorQTextStream( QTextStream& stream ) : m_stream(stream) , m_peekStart(-1) { } bool IteratorQTextStream::hasMoreLines() const { return !m_stream.atEnd(); } std::string IteratorQTextStream::nextLine(bool emptyLineWasDeleted) { Q_UNUSED(emptyLineWasDeleted) return m_stream.readLine().toStdString(); } string IteratorQTextStream::peekNextLine() { if (m_peekStart == -1) { m_peekStart = m_stream.pos(); } return m_stream.readLine().toUtf8().data(); } void IteratorQTextStream::peekReset() { if(m_peekStart != -1) m_stream.seek(m_peekStart); m_peekStart = -1; // invalid } void format(QTextStream& in, const QString& oname) { QFile ofile(oname); ofile.open(QIODevice::WriteOnly); QTextStream out(&ofile); astyle::ASFormatter f; f.setCStyle(); f.setBlockIndent(false); f.setBracketIndent(false); f.setSpaceIndentation(4); f.setTabSpaceConversionMode(true); f.setMinConditionalIndentLength(f.getIndentLength()); f.setMaxInStatementIndentLength(40); f.setOperatorPaddingMode(false); f.setBracketFormatMode(astyle::BREAK_MODE); f.setClassIndent(false); f.setSwitchIndent(false); f.setNamespaceIndent(false); f.setBreakElseIfsMode(false); f.setParensUnPaddingMode(false); f.setEmptyLineFill(false); IteratorQTextStream strm(in); f.init(&strm); do { out << QString::fromStdString( f.nextLine() ) << endl; } while (f.hasMoreLines()); } } diff --git a/kdev-pg/kdev-pg-beautifier.h b/kdev-pg/kdev-pg-beautifier.h index d96df64..b395f58 100644 --- a/kdev-pg/kdev-pg-beautifier.h +++ b/kdev-pg/kdev-pg-beautifier.h @@ -1,51 +1,51 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_BEAUTIFIER_H #define KDEV_PG_BEAUTIFIER_H -#include +#include #include "astyle.h" #include namespace KDevPG { class IteratorQTextStream : public astyle::ASSourceIterator { public: IteratorQTextStream(QTextStream& stream); bool hasMoreLines() const override; std::string nextLine(bool emptyLineWasDeleted = false) override; std::string peekNextLine() override; void peekReset() override; private: QTextStream& m_stream; qint64 m_peekStart; }; void format(QTextStream &in, const QString& oname); } #endif // KDEV_PG_BEAUTIFIER_H diff --git a/kdev-pg/kdev-pg-checker.cpp b/kdev-pg/kdev-pg-checker.cpp index 38f91c9..deb4317 100644 --- a/kdev-pg/kdev-pg-checker.cpp +++ b/kdev-pg/kdev-pg-checker.cpp @@ -1,440 +1,440 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2006 Alexander Dymo This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-checker.h" #include "kdev-pg-pretty-printer.h" #include "kdev-pg-bnf-visitor.h" -#include +#include //uncomment this to see debug output for follow checker // #define FOLLOW_CHECKER_DEBUG namespace KDevPG { QTextStream checkOut(stderr); int ProblemSummaryPrinter::mFirstFirstConflictCount = 0; int ProblemSummaryPrinter::mFirstFollowConflictCount = 0; int ProblemSummaryPrinter::mErrorCount = 0; void FirstFirstConflictChecker::operator()(Model::Node *node) { Model::EvolveItem *e = nodeCast(node); Q_ASSERT(e != nullptr); mSymbol = e->mSymbol; visitNode(node); } void FirstFirstConflictChecker::visitAlternative(Model::AlternativeItem *node) { DefaultVisitor::visitAlternative(node); mCheckedNode = node; check(node->mLeft, node->mRight); } void FirstFirstConflictChecker::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) { Q_UNUSED(node); } void FirstFirstConflictChecker::check(Model::Node *left, Model::Node *right) { World::NodeSet const &left_first = globalSystem.first(left); World::NodeSet const &right_first = globalSystem.first(right); QSet U = left_first; U.intersect( right_first ); if (!U.empty()) { QTextStream& str( checkOut ); PrettyPrinter printer(str); str << "** WARNING found FIRST/FIRST conflict in " << mSymbol->mName << ":" << endl << "\tRule ``"; printer(mCheckedNode); // p(left); str << "''" << endl << "\tTerminals [" << endl; QSet::iterator it = U.begin(); while (it != U.end()) { Model::Node *n = *it++; str << "\t\t" << n; if (it != U.end()) str << ", "; str << endl; } str << "\t]" << endl << endl; ProblemSummaryPrinter::reportFirstFirstConflict(); } } void FirstFirstConflictChecker::visitEvolve(Model::EvolveItem *node) { DefaultVisitor::visitEvolve(node); World::Environment::iterator it = globalSystem.env.find(node->mSymbol); while (it != globalSystem.env.end()) { Model::SymbolItem *sym = it.key(); Model::EvolveItem *e = (*it); ++it; if (sym != node->mSymbol || node == e) continue; mCheckedNode = node; check(e, node); } } void FirstFollowConflictChecker::operator()(Model::Node *node) { Model::EvolveItem *e = nodeCast(node); Q_ASSERT(e != nullptr); mSymbol = e->mSymbol; visitNode(node); } void FirstFollowConflictChecker::check(Model::Node *node, Model::Node *sym) { if (!sym) sym = node; World::NodeSet const &first = globalSystem.first(node); World::NodeSet const &follow = globalSystem.follow(sym); QSet U = first; U.intersect(follow); if (!U.empty()) { QTextStream& str( checkOut ); PrettyPrinter p(str); str << "** WARNING found FIRST/FOLLOW conflict in " << mSymbol->mName; #ifdef FOLLOW_CHECKER_DEBUG str << "(" << (uint*)mSymbol << ")"; #endif str << ":" << endl << "\tRule ``"; p(node); #ifdef FOLLOW_CHECKER_DEBUG str << " [[" << (uint*)node << "]]"; #endif str << "''" << endl << "\tTerminals [" << endl; QSet::iterator it = U.begin(); while (it != U.end()) { Model::Node *n = *it++; if (isZero(n)) continue; str << "\t\t" << ((Model::TerminalItem*)n)->mName << ": conflicts with the FIRST set of: " << endl; FollowDepChecker(n).check(node); if (it != U.end()) str << "," << endl; } str << "\t]" << endl << endl; ProblemSummaryPrinter::reportFirstFollowConflict(); } } void FollowDepChecker::check(Model::Node *node) { //avoid cyclical follow dependency check if (mVisited.find(node) != mVisited.end()) return; mVisited.insert(node); World::FollowDep &D = globalSystem.followDep(node); QList FD = D.first.toList(); QList FLD = D.second.toList(); QTextStream& str( checkOut ); PrettyPrinter p(str); #ifdef FOLLOW_CHECKER_DEBUG str << "[["; p(node); str << " | " << (uint*)node << "]] "; str << "{" << node->kind << "}" << endl; #endif for (int i = 0; i != FD.size(); ++i) // no iterator → modifiable { if(BnfVisitor::isInternal(FD[i])) { World::NodeSet set = globalSystem.followDep(FD[i]).second; World::NodeSet set2 = globalSystem.followDep(FD[i]).first; // :-S has to be verified… for(auto jt = FD.begin(); jt != FD.end(); ++jt) { set.remove(*jt); set2.remove(*jt); } for(auto jt = set2.begin(); jt != set2.end(); ++jt) if(!BnfVisitor::isInternal(*jt)) FD.append(*jt); FD.append(set.toList()); } else { World::NodeSet first = globalSystem.first(FD[i]); #ifdef FOLLOW_CHECKER_DEBUG str << " "; #endif if (first.find(mTerminal) != first.end()) { str << "\t\t"; p(FD[i]); #ifdef FOLLOW_CHECKER_DEBUG str << " ( in \""; p(node); str << " \" )"; #endif str << ", " << endl; } } } for (int i = 0; i != FLD.size(); ++i) { if(BnfVisitor::isInternal(FLD[i])) { World::NodeSet set = globalSystem.followDep(FLD[i]).second; for(auto jt = FLD.begin(); jt != FLD.end(); ++jt) set.remove(*jt); FLD.append(set.toList()); } else { World::NodeSet first = globalSystem.first(FLD[i]); #ifdef FOLLOW_CHECKER_DEBUG str << endl << "\t\t" << "in "; p(FLD[i]); str << endl; #endif check(FLD[i]); } } } void FirstFollowConflictChecker::visitAlternative(Model::AlternativeItem *node) { DefaultVisitor::visitAlternative(node); if (isZero(node->mRight)) return; if (reducesToEpsilon(node)) check(node); } void FirstFollowConflictChecker::visitCons(Model::ConsItem *node) { DefaultVisitor::visitCons(node); if (reducesToEpsilon(node)) check(node); } void FirstFollowConflictChecker::visitPlus(Model::PlusItem *node) { DefaultVisitor::visitPlus(node); if (reducesToEpsilon(node)) check(node); } void FirstFollowConflictChecker::visitStar(Model::StarItem *node) { DefaultVisitor::visitStar(node); check(node); } void FirstFollowConflictChecker::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) { Q_UNUSED(node); } void UndefinedSymbolChecker::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) { if(node->mSymbol) visitSymbol(node->mSymbol); } void UndefinedSymbolChecker::operator()(Model::Node *node) { Model::EvolveItem *e = nodeCast(node); Q_ASSERT(e != nullptr); mSymbol = e->mSymbol; visitNode(node); } void UndefinedSymbolChecker::visitSymbol(Model::SymbolItem *node) { if (globalSystem.env.count(node) == 0) { checkOut << "** ERROR Undefined symbol ``" << node->mName << "'' in " << mSymbol->mName << endl; ProblemSummaryPrinter::reportError(); } } void UndefinedSymbolChecker::visitVariableDeclaration(Model::VariableDeclarationItem *node) { if (node->mVariableType != Model::VariableDeclarationItem::TypeNode) return; Model::SymbolItem *sym; QString name = node->mType; World::SymbolSet::iterator it = globalSystem.symbols.find(name); if (it == globalSystem.symbols.end()) { checkOut << "** ERROR Undefined symbol ``" << name << "'' (rule parameter declaration) in " << mSymbol->mName << endl; ProblemSummaryPrinter::reportError(); return; } else sym = (*it); if (globalSystem.env.count(sym) == 0) { checkOut << "** ERROR Undefined symbol ``" << node->mName << "'' (rule parameter declaration) in " << mSymbol->mName << endl; ProblemSummaryPrinter::reportError(); } } void UndefinedTokenChecker::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) { Q_UNUSED(node); } void UndefinedTokenChecker::operator()(Model::Node *node) { Model::EvolveItem *e = nodeCast(node); Q_ASSERT(e != nullptr); mSymbol = e->mSymbol; visitNode(node); } void UndefinedTokenChecker::visitTerminal(Model::TerminalItem *node) { QString name = node->mName; if (globalSystem.terminals.find(name) == globalSystem.terminals.end()) { checkOut << "** ERROR Undefined token ``" << node->mName << "'' in " << mSymbol->mName << endl; ProblemSummaryPrinter::reportError(); } } void EmptyFirstChecker::operator()(Model::Node *node) { visitNode(node); } void EmptyFirstChecker::visitNonTerminal(Model::NonTerminalItem *node) { Q_UNUSED(node); } void EmptyFirstChecker::visitInlinedNonTerminal(Model::InlinedNonTerminalItem *node) { Q_UNUSED(node); } void EmptyFirstChecker::visitSymbol(Model::SymbolItem *node) { if (globalSystem.first(node).empty()) { checkOut << "** ERROR Empty FIRST set for ``" << node->mName << "''" << endl; ProblemSummaryPrinter::reportError(); } } void EmptyOperatorChecker::operator()(Model::Node *node) { visitNode(node); } void EmptyOperatorChecker::visitOperator(Model::OperatorItem *node) { if (reducesToEpsilon((node->mBase->mSymbol))) { checkOut << "** ERROR Base symbol ``" << node->mBase->mSymbol->mName << "'' for operator ``" << node->mName << "'' reduces to zero" << endl; ProblemSummaryPrinter::reportError(); } } void ProblemSummaryPrinter::operator()() { if (KDevPG::globalSystem.conflictHandling != KDevPG::World::Ignore) checkOut << (mFirstFirstConflictCount + mFirstFollowConflictCount) << " conflicts total: " << mFirstFollowConflictCount << " FIRST/FOLLOW conflicts, " << mFirstFirstConflictCount << " FIRST/FIRST conflicts." << endl; if (mErrorCount > 0) { checkOut << mErrorCount << " fatal errors found, exiting." << endl; exit(EXIT_FAILURE); } if (KDevPG::globalSystem.conflictHandling == KDevPG::World::Strict && mFirstFirstConflictCount + mFirstFollowConflictCount > 0) { checkOut << "Conflicts found, exiting." << endl; exit(EXIT_FAILURE); } } void ProblemSummaryPrinter::reportFirstFirstConflict() { ++mFirstFirstConflictCount; } void ProblemSummaryPrinter::reportFirstFollowConflict() { ++mFirstFollowConflictCount; } void ProblemSummaryPrinter::reportError() { ++mErrorCount; } } // kate: space-indent on; indent-width 2; tab-width 2; show-tabs on; diff --git a/kdev-pg/kdev-pg-clone-tree.h b/kdev-pg/kdev-pg-clone-tree.h index 1967c26..da906e4 100644 --- a/kdev-pg/kdev-pg-clone-tree.h +++ b/kdev-pg/kdev-pg-clone-tree.h @@ -1,57 +1,57 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_CLONE_TREE_H #define KDEV_PG_CLONE_TREE_H #include "kdev-pg-default-visitor.h" -#include +#include namespace KDevPG { class CloneTree: public DefaultVisitor { public: QStack mTemps; public: Model::Node *clone(Model::Node *node); protected: void visitZero(Model::ZeroItem *node) override; void visitSymbol(Model::SymbolItem *node) override; void visitTerminal(Model::TerminalItem *node) override; void visitNonTerminal(Model::NonTerminalItem *node) override; void visitInlinedNonTerminal(Model::InlinedNonTerminalItem *node) override; void visitPlus(Model::PlusItem *node) override; void visitStar(Model::StarItem *node) override; void visitAction(Model::ActionItem *node) override; void visitAlternative(Model::AlternativeItem *node) override; void visitCons(Model::ConsItem *node) override; void visitEvolve(Model::EvolveItem *node) override; void visitTryCatch(Model::TryCatchItem *node) override; void visitAlias(Model::AliasItem *node) override; void visitAnnotation(Model::AnnotationItem *node) override; void visitOperator(Model::OperatorItem *node) override; }; } #endif // KDEV_PG_CLONE_TREE_H diff --git a/kdev-pg/kdev-pg-code-gen.cpp b/kdev-pg/kdev-pg-code-gen.cpp index 4732a05..6216e56 100644 --- a/kdev-pg/kdev-pg-code-gen.cpp +++ b/kdev-pg/kdev-pg-code-gen.cpp @@ -1,1269 +1,1269 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2010 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-code-gen.h" -#include -#include -#include -#include +#include +#include +#include +#include #include "kdev-pg-pretty-printer.h" namespace KDevPG { extern QTextStream checkOut; void generateConditionFromStrings(QStringList &tokens, bool zerop, QTextStream& out) { tokens.sort(); bool initial = true; foreach (const QString &token, tokens) { if (!initial) out << endl << "|| "; out << "yytoken == Token_" << token; initial = false; } if (initial && zerop) out << "true /*epsilon*/"; } void generateCondition(const World::NodeSet& s, QTextStream& out) { if(s.size() == 0 || (s.size() == 1 && nodeCast(*s.begin()) != nullptr)) { out << "true /*epsilon*/"; return; } Model::Node *item = globalSystem.zero(); QStringList tokens; World::NodeSet::const_iterator it = s.begin(); while (it != s.end()) { item = *it; ++it; if (Model::TerminalItem *t = nodeCast(item)) tokens << t->mName; } generateConditionFromStrings(tokens, false, out); } void generateTestCondition(Model::Node *node, QTextStream& out) { if(node->kind == Model::NodeKindTerminal) { QStringList tokens; tokens << ((Model::TerminalItem*)node)->mName; generateConditionFromStrings(tokens, false, out); } else { World::NodeSet& s = globalSystem.first(node); generateCondition(s, out); } } QString generateParserCall(Model::NonTerminalItem *node, int catch_id, QTextStream& out) { static int __id = 0; static char __var[1024]; QString symbol_name = node->mSymbol->mName; QString capSymbolName = node->mSymbol->mCapitalizedName; if (globalSystem.generateAst) { sprintf(__var, "__node_%d", __id); ++__id; out << capSymbolName << "Ast *" << __var << " = 0;" << endl << "if (!parse" << capSymbolName << "(&" << __var; if (!node->mArguments.isEmpty()) out << ", " << node->mArguments; out << "))" << endl; } else { out << "if (!parse" << capSymbolName << "(" << node->mArguments << "))" << endl; } if (!catch_id) { out << "{" << endl; if (globalSystem.needStateManagement) out << "if (!mBlockErrors) {" << endl; out << "expectedSymbol(AstNode::" << capSymbolName << "Kind" << ", QStringLiteral(\"" << symbol_name << "\")" << ");" << endl; if (globalSystem.needStateManagement) out << "}" << endl; out << "return false;" << endl << "}" << endl; } else { out << "{ goto __catch_" << catch_id << "; }" << endl; } return __var; } void generateTokenTest(Model::TerminalItem *node, int catch_id, QTextStream& out) { out << "if (yytoken != Token_" << node->mName << ")" << endl; if (!catch_id) { out << "{" << endl; if (globalSystem.needStateManagement) out << "if (!mBlockErrors) {" << endl; out << "expectedToken(yytoken, Token_" << node->mName << ", QStringLiteral(\"" << node->mDescription << "\"));" << endl; if (globalSystem.needStateManagement) out << "}" << endl; out << "return false;" << endl << "}" << endl; } else { out << "goto __catch_" << catch_id << ";" << endl; } } void generateRecovery(Model::Node *node, int catch_id, QTextStream& out) { World::NodeSet s = globalSystem.follow(node); Model::Node *item = globalSystem.zero(); out << "if (try_startToken_" << catch_id << " == tokenStream->index() - 1 && yytoken != Token_EOF)" << endl << "yylex();" << endl << endl; out << "while (yytoken != Token_EOF"; World::NodeSet::iterator it = s.begin(); while (it != s.end()) { item = *it; ++it; if (Model::TerminalItem *t = nodeCast(item)) out << endl << "&& yytoken != Token_" << t->mName; } out << ")" << endl << "{ yylex(); }" << endl; } void CodeGenerator::operator()(Model::Node *node) { mEvolve = nodeCast(node); Q_ASSERT(mEvolve != nullptr); visitNode(node); } void CodeGenerator::visitZero(Model::ZeroItem *node) { Q_UNUSED(node); // out << " /* nothing to do */" << endl; } void CodeGenerator::visitSymbol(Model::SymbolItem *node) { Q_UNUSED(node); // out << " /* nothing to do */" << endl; } void CodeGenerator::visitNonTerminal(Model::NonTerminalItem *node) { generateParserCall(node, mCurrentCatchId, out); } void CodeGenerator::visitTerminal(Model::TerminalItem *node) { generateTokenTest(node, mCurrentCatchId, out); out << "yylex();" << endl << endl; } void CodeGenerator::visitPlus(Model::PlusItem *node) { out << "do {" << endl; visitNode(node->mItem); out << "} while ("; generateTestCondition(node, out); out << ");" << endl; } void CodeGenerator::visitStar(Model::StarItem *node) { out << "while ("; generateTestCondition(node, out); out << ") {" << endl; visitNode(node->mItem); out << "}" << endl; } void CodeGenerator::visitAction(Model::ActionItem *node) { DefaultVisitor::visitAction(node); out << node->mCode; } void CodeGenerator::visitCondition(Model::ConditionItem *node) { DefaultVisitor::visitCondition(node); } void CodeGenerator::visitAlternative(Model::AlternativeItem *node) { QList top_level_nodes; QStack working_list; working_list.push(node->mRight); working_list.push(node->mLeft); while (!working_list.empty()) { Model::Node *n = working_list.top(); working_list.pop(); if (Model::AlternativeItem *a = nodeCast(n)) { working_list.push(a->mRight); working_list.push(a->mLeft); } else { top_level_nodes.push_back(n); } } QList::iterator it = top_level_nodes.begin(); while (it != top_level_nodes.end()) { Model::Node *n = *it; ++it; Model::ConditionItem *cond = nodeCast(n); out << "if ("; if (cond) out << "("; generateTestCondition(n, out); if (cond) out << ") && (" << cond->mCode << ")"; out << ") {" << endl; visitNode(n); out << "}"; if (it != top_level_nodes.end()) out << "else "; else { out << "else {" << endl; if (!mCurrentCatchId) out << "return false;" << endl; else out << "goto __catch_" << mCurrentCatchId << ";"; out << "}" << endl; } } } void CodeGenerator::visitCons(Model::ConsItem *node) { DefaultVisitor::visitCons(node); } void CodeGenerator::visitEvolve(Model::EvolveItem *node) { out << "if ("; Model::ConditionItem *cond = nodeCast(node->mItem); if (cond) out << "("; generateTestCondition(node, out); if (reducesToEpsilon(node->mItem)) { out << " || "; generateCondition(globalSystem.follow(node->mSymbol), out); } if (cond) out << ") && (" << cond->mCode << ")"; out << ") {" << endl; GenerateLocalDeclarations gen_locals(out, mNames); gen_locals(node->mItem); out << node->mCode; visitNode(node->mItem); if (globalSystem.start.contains(node->mSymbol)) out << "if (Token_EOF != yytoken) { return false; }" << endl; out << "}" << endl; } void CodeGenerator::visitTryCatch(Model::TryCatchItem *node) { static int tryCatch_counter = 0; int previous_catch_id = setCatchId(++tryCatch_counter); if (node->mCatchItem) // node is a try/rollback block { out << "bool blockErrors_" << mCurrentCatchId << " = blockErrors(true);" << endl; } out << "qint64 try_startToken_" << mCurrentCatchId << " = tokenStream->index() - 1;" << endl; if (!node->mUnsafe) { out << "ParserState *try_startState_" << mCurrentCatchId << " = copyCurrentState();" << endl; } out << "{" << endl; visitNode(node->mTryItem); out << "}" << endl; if (node->mCatchItem) { out << "blockErrors(blockErrors_" << mCurrentCatchId << ");" << endl; } if (!node->mUnsafe) { out << "if (try_startState_" << mCurrentCatchId << ")" << endl << "delete try_startState_" << mCurrentCatchId << ";" << endl << endl; } out << "if (false) // the only way to enter here is using goto" << endl << "{" << endl << "__catch_" << mCurrentCatchId << ":" << endl; if (!node->mUnsafe) { out << "if (try_startState_" << mCurrentCatchId << ")" << endl << "{" << endl << "restoreState(try_startState_" << mCurrentCatchId << ");" << endl << "delete try_startState_" << mCurrentCatchId << ";" << endl << "}" << endl; } if (!node->mCatchItem) { generateRecovery(node, mCurrentCatchId, out); setCatchId(previous_catch_id); } else { out << "blockErrors(blockErrors_" << mCurrentCatchId << ");" << endl << "rewind(try_startToken_" << mCurrentCatchId << ");" << endl << endl; setCatchId(previous_catch_id); visitNode(node->mCatchItem); } out << "}" << endl << endl; } int CodeGenerator::setCatchId(int catch_id) { int previous = mCurrentCatchId; mCurrentCatchId = catch_id; return previous; } void CodeGenerator::visitAlias(Model::AliasItem *node) { Q_UNUSED(node); Q_ASSERT(0); // ### not implemented yet } void CodeGenerator::visitAnnotation(Model::AnnotationItem *node) { if (!globalSystem.generateAst) { // checkOut << "** WARNING annotation ignored" << endl; visitNode(node->mItem); return; } if (Model::TerminalItem *t = nodeCast(node->mItem)) { generateTokenTest(t, mCurrentCatchId, out); if (node->mDeclaration->mIsSequence) { QString target; if (node->mDeclaration->mStorageType == Model::VariableDeclarationItem::StorageAstMember) target += "(*yynode)->"; target += node->mDeclaration->mName; target += "Sequence"; out << target << " = snoc(" << target << ", " << "tokenStream->index() - 1, memoryPool);" << endl << "yylex();" << endl << endl; } else { if (node->mDeclaration->mStorageType == Model::VariableDeclarationItem::StorageAstMember) out << "(*yynode)->"; out << node->mDeclaration->mName << " = tokenStream->index() - 1;" << endl << "yylex();" << endl << endl; } } else if (Model::NonTerminalItem *nt = nodeCast(node->mItem)) { QString __var = generateParserCall(nt, mCurrentCatchId, out); bool check_startToken = false; World::Environment::iterator it = globalSystem.env.find(nt->mSymbol); while (it != globalSystem.env.end()) { Model::EvolveItem *e = (*it); if (it.key() != nt->mSymbol) break; ++it; Model::VariableDeclarationItem *current_decl = e->mDeclarations; while (current_decl) { if ((current_decl->mDeclarationType == Model::VariableDeclarationItem::DeclarationArgument) && (current_decl->mVariableType != Model::VariableDeclarationItem::TypeVariable)) { check_startToken = true; break; } current_decl = current_decl->mNext; } } if (check_startToken == true) { check_startToken = false; Model::VariableDeclarationItem *current_decl = mEvolve->mDeclarations; while (current_decl) { if ((current_decl->mStorageType == Model::VariableDeclarationItem::StorageTemporary) && (current_decl->mVariableType != Model::VariableDeclarationItem::TypeVariable) && (current_decl->mDeclarationType == Model::VariableDeclarationItem::DeclarationArgument)) { check_startToken = true; break; } current_decl = current_decl->mNext; } } if (check_startToken == true) { out << "if (" << __var << "->startToken < (*yynode)->startToken)" << endl << "(*yynode)->startToken = " << __var << "->startToken;" << endl; } QString target; if (node->mDeclaration->mStorageType == Model::VariableDeclarationItem::StorageAstMember) target += "(*yynode)->"; target += node->mDeclaration->mName; if (node->mDeclaration->mIsSequence) { target += "Sequence"; out << target << " = " << "snoc(" << target << ", " << __var << ", memoryPool);" << endl << endl; } else { out << target << " = " << __var << ";" << endl << endl; } } else Q_ASSERT(0); // ### not supported } void CodeGenerator::visitOperator(Model::OperatorItem *node) { out << "bool expectOperator = false;" << "while(true) {" << "if(expectOperator) {" << " "; const QString capNode = capitalized(node->mName); const QString nodeType = capNode + "Ast"; const QString baseNameC = node->mBase->mSymbol->mCapitalizedName; const QString baseType = baseNameC + "Ast"; Model::NonTerminalItem ntItem; ntItem.mSymbol = mSym; ntItem.kind = Model::NodeKindNonTerminal; { QTextStream argStr(&ntItem.mArguments); GenerateRecursiveDelegation del(argStr); } bool printElse = false; for(auto i = node->mPost.begin(); i != node->mPost.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create(last), -2));" "(*yynode)->endToken = last->endToken + 1;" "(*yynode)->startToken = last->startToken;" "br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = opStack.last().n->kind == AstNode::Binary" << capNode << "Kind && ((Binary" << nodeType << "*)opStack.last().n)->second ? ((Binary" << nodeType << "*)opStack.last().n)->second : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create(last), -2));" "ref->endToken = last->endToken + 1;" "ref->startToken = last->startToken;" "} yylex(); }"; } for(auto i = node->mBin.begin(); i != node->mBin.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;\n" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create(last), priority));" "(*yynode)->startToken = last->startToken;" "br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = " "opStack.last().n->kind == AstNode::Ternary" << capNode << "Kind" " ? (((Ternary" << nodeType << "*)opStack.last().n)->third" " ? ((Ternary" << nodeType << "*)opStack.last().n)->third" " : (((Ternary" << nodeType << "*)opStack.last().n)->second" " ? ((Ternary" << nodeType << "*)opStack.last().n)->second" " : ((Ternary" << nodeType << "*)opStack.last().n)->first ))" " : opStack.last().n->kind == AstNode::Binary" << capNode << "Kind" " && ((Binary" << nodeType << "*)opStack.last().n)->second" " ? ((Binary" << nodeType << "*)opStack.last().n)->second" " : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create(last), priority)); ref->startToken = last->startToken; } expectOperator = false; yylex(); }"; } for(auto i = node->mTern.begin(); i != node->mTern.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->first.mTok, out); if(i->first.mCond.size() != 0) out << " && " << i->first.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->first.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;\n" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create(last), priority));" "(*yynode)->startToken = last->startToken;" "yylex();"; QString __var = generateParserCall(&ntItem, mCurrentCatchId, out); out << "if(!("; generateTestCondition(i->second.mTok, out); if(i->second.mCond.size() != 0) out << " && " << i->second.mCond; out << ")) return false;" "((Ternary" << nodeType << "*)*yynode)->second = " << __var << ";br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = " "opStack.last().n->kind == AstNode::Ternary" << capNode << "Kind" " ? (((Ternary" << nodeType << "*)opStack.last().n)->third" " ? ((Ternary" << nodeType << "*)opStack.last().n)->third" " : (((Ternary" << nodeType << "*)opStack.last().n)->second" " ? ((Ternary" << nodeType << "*)opStack.last().n)->second" " : ((Ternary" << nodeType << "*)opStack.last().n)->first ))" " : opStack.last().n->kind == AstNode::Binary" << capNode << "Kind" " && ((Binary" << nodeType << "*)opStack.last().n)->second" " ? ((Binary" << nodeType << "*)opStack.last().n)->second" " : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create(last), priority)); ref->startToken = last->startToken; } expectOperator = false; yylex(); }"; } out << "else "; out << "break;"; out << "} else {"; printElse = false; for(auto i = node->mPre.begin(); i != node->mPre.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode << "Prefix" << nodeType << " *node = create();" "if(opStack.empty())\n" "(*yynode) = node;" "else" "{\n" "void *last = opStack.last().n;" "if(reinterpret_cast(last)->first == 0)\n" "reinterpret_cast(last)->first = node;" "else if(reinterpret_cast(last)->second == 0)\n" "reinterpret_cast(last)->second = node;" "else\n" "reinterpret_cast(last)->third = node;" "}" "opStack.push_back(OperatorStackItem(node, priority));" "node->startToken = tokenStream->index() - 1;" "yylex();" "}" << endl; } for(auto i = node->mParen.begin(); i != node->mParen.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->first.mTok, out); if(i->first.mCond.size() != 0) out << " && " << i->first.mCond; out << ") { yylex();" "if("; generateTestCondition(mSym, out); out << ") {"; QString __var = generateParserCall(&ntItem, mCurrentCatchId, out); out << "if(!("; generateTestCondition(i->second.mTok, out); if(i->second.mCond.size() != 0) out << " && " << i->second.mCond; out << ")) {" "return false;" "}" "--" << __var << "->startToken;" "++" << __var << "->endToken;" "yylex();"; #define PUSH_UNARY \ out << "\ if(!opStack.isEmpty())\ {\ void *last = opStack.last().n;\ if(reinterpret_cast(last)->first == 0)\n\ reinterpret_cast(last)->first = " << __var << ";" << endl; \ out << "else if(reinterpret_cast(last)->second == 0)\n\ reinterpret_cast(last)->second = " << __var << ";\ else\nreinterpret_cast(last)->third = " << __var << ";}\ else\n\ (*yynode) = " << __var << ";\ opStack.push_back(OperatorStackItem(" << __var << ", -2));"; PUSH_UNARY out << "expectOperator = true; } else\nreturn false; }"; } if(printElse) out << "else "; out << "if("; generateTestCondition(node->mBase->mSymbol, out); out << ") { "; QString __var = generateParserCall(node->mBase, mCurrentCatchId, out); PUSH_UNARY #undef PUSH_UNARY out << "expectOperator = true; }"; out << "else" "{" "expectedSymbol(AstNode::" << capNode << "Kind" ", \"" << node->mName << "\");return false;" "} } }"; /// @TODO Further: empty binary operator } void GenerateForwardParserRule::operator()(QPair const &__it) { Model::SymbolItem *sym = __it.second; out << "bool" << " " << "parse" << sym->mCapitalizedName << "("; GenerateParseMethodSignature gen_signature(out, nullptr); gen_signature(sym); out << ");" << endl; } void GenerateParserRule::operator()(QPair const &__it) { mNames.clear(); Model::SymbolItem *sym = __it.second; CodeGenerator cg(out, &mNames, sym); out << "bool Parser::parse" << sym->mCapitalizedName << "("; GenerateParseMethodSignature gen_signature(out, &mNames); gen_signature(sym); out << ")" << endl << "{" << endl; if (globalSystem.generateAst) { if(isOperatorSymbol(sym)) out << "QVector opStack;" << endl; else { out << "*yynode = create<" << sym->mCapitalizedName << "Ast" << ">();" << endl << endl << "(*yynode)->startToken = tokenStream->index() - 1;" << endl; //Generate initialization for this ast nodes token-members using -1 as invalid value GenerateTokenVariableInitialization gentokenvar( out ); gentokenvar(sym); out << endl; } } World::Environment::iterator it = globalSystem.env.find(sym); GenerateLocalDeclarations gen_locals(out, &mNames); while (it != globalSystem.env.end()) { Model::EvolveItem *e = (*it); if (it.key() != sym) break; ++it; gen_locals(e->mDeclarations); } it = globalSystem.env.find(sym); bool initial = true; while (it != globalSystem.env.end()) { Model::EvolveItem *e = (*it); if (it.key() != sym) break; ++it; if (!initial) out << "else "; cg(e); initial = false; } out << "else" << endl << "{ return false; }" << endl << endl; if (globalSystem.generateAst) { if(isOperatorSymbol(sym)) { out << "AstNode *olast, *last = 0;" "while(!opStack.empty())\n" "{" "olast = last;" "last = opStack.last().n;" "if(olast)\n" "last->endToken = olast->endToken;" "opStack.pop_back();" "}" << endl; } else { out << "(*yynode)->endToken = tokenStream->index() - 2;" << endl << endl; } } out << "return true;" << endl << "}" << endl << endl; } void GenerateLocalDeclarations::operator()(Model::Node *node) { visitNode(node); } void GenerateLocalDeclarations::visitVariableDeclaration(Model::VariableDeclarationItem *node) { // normal declarations for local variables if (node->mStorageType == Model::VariableDeclarationItem::StorageTemporary && node->mDeclarationType == Model::VariableDeclarationItem::DeclarationLocal) { if ((mNames == nullptr) || mNames->find(node->mName) == mNames->end()) { GenerateVariableDeclaration gen_var_decl(out); gen_var_decl(node); if (node->mVariableType == Model::VariableDeclarationItem::TypeToken || node->mVariableType == Model::VariableDeclarationItem::TypeNode || node->mIsSequence) { out << " = 0"; } out << ";" << endl << endl; if (mNames != nullptr) mNames->insert(node->mName); } } // for argument member nodes and tokens, check if their index precedes the current one else if (node->mStorageType == Model::VariableDeclarationItem::StorageAstMember && node->mDeclarationType == Model::VariableDeclarationItem::DeclarationArgument && globalSystem.generateAst) { QString sequence_suffix = (node->mIsSequence) ? "Sequence" : ""; out << "(*yynode)->" << node->mName << sequence_suffix << " = " << node->mName << sequence_suffix << ";" << endl; if (node->mVariableType != Model::VariableDeclarationItem::TypeVariable) { QString argument_startToken = node->mName; if (node->mIsSequence) argument_startToken += "Sequence->front()->element"; if (node->mVariableType == Model::VariableDeclarationItem::TypeNode) argument_startToken += "->startToken"; out << "if ("; // check that the variable is not null if (node->mVariableType == Model::VariableDeclarationItem::TypeNode || node->mIsSequence) { out << node->mName << sequence_suffix << " && "; } out << argument_startToken << " < (*yynode)->startToken)" << endl << "(*yynode)->startToken = " << argument_startToken << ";" << endl << endl; } } DefaultVisitor::visitVariableDeclaration(node); } void GenerateParseMethodSignature::operator()(Model::SymbolItem* sym) { if (globalSystem.generateAst) { out << sym->mCapitalizedName << "Ast **yynode"; firstParameter = false; } World::Environment::iterator it = globalSystem.env.find(sym); if (it != globalSystem.env.end()) { // this creates the method signature using just the first of // possibly multiple rules with the same name. Model::EvolveItem *e = (*it); if (e->mDeclarations) visitNode(e->mDeclarations); } } void GenerateRecursiveDelegation::operator()(Model::SymbolItem* node) { World::Environment::iterator it = globalSystem.env.find(node); if (it != globalSystem.env.end()) { // this creates the method signature using just the first of // possibly multiple rules with the same name. Model::EvolveItem *e = (*it); Model::VariableDeclarationItem *decl = e->mDeclarations; GenerateVariableDeclaration vd(out); while(decl) { vd(decl); decl = decl->mNext; } } } void GenerateParseMethodSignature::visitVariableDeclaration(Model::VariableDeclarationItem *node) { if (node->mDeclarationType == Model::VariableDeclarationItem::DeclarationArgument) { if (globalSystem.generateAst || (node->mStorageType != Model::VariableDeclarationItem::StorageAstMember)) { if (firstParameter) firstParameter = false; else out << ", "; GenerateVariableDeclaration gen_var_decl(out); gen_var_decl(node); if (mNames != nullptr) mNames->insert(node->mName); } } DefaultVisitor::visitVariableDeclaration(node); } template void GenerateVariableDeclaration::operator()(Model::VariableDeclarationItem *node) { if(printType) { if (node->mIsSequence) out << "const KDevPG::ListNode<"; if (node->mVariableType == Model::VariableDeclarationItem::TypeToken) out << "qint64 "; else if (node->mVariableType == Model::VariableDeclarationItem::TypeNode) { out << node->mCapitalizedType << "Ast *"; }else if (node->mVariableType == Model::VariableDeclarationItem::TypeVariable) out << node->mType << " "; else Q_ASSERT(0); // ### not supported if (node->mIsSequence) out << "> *"; } if(printName) { out << node->mName; if (node->mIsSequence) out << "Sequence"; } } void GenerateMemberCode::operator()(Settings::MemberItem* m) { if ((mKindMask & m->mMemberKind) != 0) { if (m->mMemberKind == Settings::MemberItem::PublicDeclaration) out << "public:" << endl; else if (m->mMemberKind == Settings::MemberItem::ProtectedDeclaration) out << "protected:" << endl; else if (m->mMemberKind == Settings::MemberItem::PrivateDeclaration) out << "private:" << endl; out << m->mCode << endl; } } void GenerateParserDeclarations::operator()() { out << "class " << globalSystem.exportMacro << " Parser : "; if(!globalSystem.parserBaseClass.isEmpty()) out << "public " << globalSystem.parserBaseClass << ", "; out << "public TokenTypeWrapper\n{" << "public:" << endl << "typedef " << globalSystem.tokenStream << "::Token Token;" << endl << globalSystem.tokenStream << " *tokenStream;" << endl << "int yytoken;" << endl; if(globalSystem.needOperatorStack) out << "struct OperatorStackItem{AstNode *n; int unsigned p;" "inline OperatorStackItem(AstNode *n, int unsigned p)\n" ": n(n), p(p)\n{}\n" "inline OperatorStackItem()\n{}\n" "inline OperatorStackItem(const OperatorStackItem& o)\n" ": n(o.n), p(o.p)\n" "{}\n};" << endl; out << endl << "inline Token LA(qint64 k = 1) const" << endl << "{ qint64 idx = tokenStream->index() - 1 + k - 1; qint64 oldidx = tokenStream->index(); tokenStream->rewind(tokenStream->size()); while(idx >= tokenStream->size()) tokenStream->read(); tokenStream->rewind(oldidx); return tokenStream->at(idx); }" << endl << "inline int yylex() {" << endl << "yytoken = tokenStream->read().kind; return yytoken;" << endl << "}" << endl << "inline void rewind(qint64 index) {" << endl << "tokenStream->rewind(index);" << endl << "yylex();" << endl << "}" << endl << endl; out << "// token stream" << endl << "void setTokenStream(" << globalSystem.tokenStream << " *s)" << endl << "{ tokenStream = s; }" << endl << endl; out << "// error handling" << endl << "void expectedSymbol(int kind, const QString& name);" << endl << "void expectedToken(int kind, qint64 token, const QString& name);" << endl << endl << "bool mBlockErrors;" << endl << "inline bool blockErrors(bool block) {" << endl << "bool previous = mBlockErrors;" << endl << "mBlockErrors = block;" << endl << "return previous;" << endl << "}" << endl; out << endl; if (globalSystem.generateAst) { out << "// memory pool" << endl << "typedef KDevPG::MemoryPool memoryPoolType;" << endl << endl << "KDevPG::MemoryPool *memoryPool;" << endl << "void setMemoryPool(KDevPG::MemoryPool *p)" << endl << "{ memoryPool = p; }" << endl << "template " << endl << "inline T *create()" << endl << "{" << endl << "T *node = new (memoryPool->allocate(sizeof(T))) T();" << endl << "node->kind = T::KIND;" << endl << "return node;" << endl << "}" << endl << "template " << endl << "inline T *create(AstNode *u)" << endl << "{" << endl << "T *node = new (memoryPool->allocate(sizeof(T))) T(u);" << endl << "node->kind = T::KIND;" << endl << "return node;" << endl << "}" << endl << endl; } if (globalSystem.parserclassMembers.declarations.empty() == false) { out << "// user defined declarations:" << endl; GenerateMemberCode gen(out, Settings::MemberItem::PublicDeclaration | Settings::MemberItem::ProtectedDeclaration | Settings::MemberItem::PrivateDeclaration); for( QList::iterator it = globalSystem.parserclassMembers.declarations.begin(); it != globalSystem.parserclassMembers.declarations.end(); ++it ) { gen(*it); } out << endl << "public:" << endl; } if (globalSystem.needStateManagement) { out << "// The copyCurrentState() and restoreState() methods are only declared" << endl << "// if you are using try blocks in your grammar, and have to be" << endl << "// implemented by yourself, and you also have to define a" << endl << "// \"struct ParserState\" inside a %parserclass directive." << endl << endl << "// This method should create a new ParserState object and return it," << endl << "// or return 0 if no state variables need to be saved." << endl << "ParserState *copyCurrentState();" << endl << endl << "// This method is only called for ParserState objects != 0" << endl << "// and should restore the parser state given as argument." << endl << "void restoreState(ParserState *state);" << endl; } out << "Parser() {" << endl; if (globalSystem.generateAst) { out << "memoryPool = 0;" << endl; } out << "tokenStream = 0;" << endl << "yytoken = Token_EOF;" << endl << "mBlockErrors = false;" << endl; if (globalSystem.parserclassMembers.constructorCode.empty() == false) { out << endl << "// user defined constructor code:" << endl; GenerateMemberCode gen(out, Settings::MemberItem::ConstructorCode); for(QList::iterator it = globalSystem.parserclassMembers.constructorCode.begin(); it != globalSystem.parserclassMembers.constructorCode.end(); ++it ) { gen(*it); } } out << "}" << endl << endl; out << "virtual ~Parser() {"; if (globalSystem.parserclassMembers.destructorCode.empty() == false) { out << endl << "// user defined destructor code:" << endl; GenerateMemberCode gen(out, Settings::MemberItem::DestructorCode); for(QList::iterator it = globalSystem.parserclassMembers.destructorCode.begin(); it != globalSystem.parserclassMembers.destructorCode.end(); ++it ) { gen(*it); } } out << "}" << endl << endl; GenerateForwardParserRule genfwdparserrule(out); for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it ) { genfwdparserrule(qMakePair(it.key(), *it)); } out << "};" << endl; } void GenerateParserBits::operator()() { GenerateParserRule gen(out); for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it ) { gen(qMakePair(it.key(), *it)); } } void GenerateTokenVariableInitialization::operator()(Model::SymbolItem* sym) { World::Environment::iterator it = globalSystem.env.find(sym); if (it != globalSystem.env.end()) { // this creates the method signature using just the first of // possibly multiple rules with the same name. Model::EvolveItem *e = (*it); if (e->mItem) visitNode(e->mItem); } } void GenerateTokenVariableInitialization::visitVariableDeclaration(Model::VariableDeclarationItem *node) { if( node->mVariableType == Model::VariableDeclarationItem::TypeToken ) { if( !node->mIsSequence ) out << "(*yynode)->" << node->mName << " = -1;" << endl; } } void GenerateTokenTexts::operator()() { out << "switch (token) {" << endl; for(World::TerminalSet::iterator it = globalSystem.terminals.begin(); it != globalSystem.terminals.end(); ++it ) { Model::TerminalItem* t = *it; out << " case TokenTypeWrapper::Token_" << t->mName << ":" << endl; QString text = t->mDescription; text.replace('\\', "\\\\").replace('"', "\\\""); out << " return QStringLiteral(\"" << text << "\");" << endl; } out << " default:" << endl; out << " return QStringLiteral(\"unknown token\");" << endl; out << "}" << endl; } } // namespace KDevPG diff --git a/kdev-pg/kdev-pg-debug-visitor-gen.h b/kdev-pg/kdev-pg-debug-visitor-gen.h index 081adb9..88063fb 100644 --- a/kdev-pg/kdev-pg-debug-visitor-gen.h +++ b/kdev-pg/kdev-pg-debug-visitor-gen.h @@ -1,65 +1,65 @@ /* This file is part of kdev-pg-qt Copyright (C) 2006 Alexander Dymo This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_DEBUG_VISITORGEN_H #define KDEV_PG_DEBUG_VISITORGEN_H #include "kdev-pg-default-visitor.h" #include "kdev-pg-default-visitor-bits-gen.h" // for the HasMemberNodes class -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateDebugVisitor { public: QTextStream& out; public: GenerateDebugVisitor(QTextStream& o): out(o) {} void operator()(); }; class GenerateDebugVisitorRule: protected DefaultVisitor { QTextStream& out; QSet mNames; public: GenerateDebugVisitorRule(QTextStream& o): out(o) {} void operator()(QPair const &__it); protected: void visitVariableDeclaration(Model::VariableDeclarationItem *node) override; }; } #endif // KDEV_PG_DEBUG_VISITORGEN_H // kate: space-indent on; indent-width 2; tab-width 2; replace-tabs on diff --git a/kdev-pg/kdev-pg-default-visitor-bits-gen.h b/kdev-pg/kdev-pg-default-visitor-bits-gen.h index 2f499a9..1925d9d 100644 --- a/kdev-pg/kdev-pg-default-visitor-bits-gen.h +++ b/kdev-pg/kdev-pg-default-visitor-bits-gen.h @@ -1,68 +1,68 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_DEFAULT_VISITOR_BITS_GEN_H #define KDEV_PG_DEFAULT_VISITOR_BITS_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include +#include +#include +#include namespace KDevPG { class GenerateDefaultVisitorBitsRule: protected DefaultVisitor { public: QTextStream& out; QString name; QSet mNames; QList mVariableDeclarations; public: explicit GenerateDefaultVisitorBitsRule(QTextStream& o, const QString& n = "DefaultVisitor"): out(o), name(n) {} void operator()(QPair const &__it); protected: void visitVariableDeclaration(Model::VariableDeclarationItem *node) override; }; class HasMemberNodes: protected DefaultVisitor { public: bool &has_members; public: HasMemberNodes(bool &result): has_members(result) {} void operator()(Model::SymbolItem *sym); protected: void visitVariableDeclaration(Model::VariableDeclarationItem *node) override; }; } #endif // KDEV_PG_DEFAULT_VISITOR_BITS_GEN_H diff --git a/kdev-pg/kdev-pg-default-visitor-gen.h b/kdev-pg/kdev-pg-default-visitor-gen.h index 86a950d..51550ca 100644 --- a/kdev-pg/kdev-pg-default-visitor-gen.h +++ b/kdev-pg/kdev-pg-default-visitor-gen.h @@ -1,62 +1,62 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_DEFAULT_VISITOR_GEN_H #define KDEV_PG_DEFAULT_VISITOR_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateDefaultVisitor { public: QTextStream& out; QString name; public: explicit GenerateDefaultVisitor(QTextStream& o, const QString& n = "DefaultVisitor"): out(o), name(n) {} void operator()(); }; class GenerateDefaultVisitorRule: protected DefaultVisitor { public: QTextStream& out; public: GenerateDefaultVisitorRule(QTextStream& o): out(o) {} void operator()(QPair const &__it); }; } #endif // KDEV_PG_DEFAULT_VISITOR_GEN_H diff --git a/kdev-pg/kdev-pg-follow.cpp b/kdev-pg/kdev-pg-follow.cpp index fefe8e8..3ed4858 100644 --- a/kdev-pg/kdev-pg-follow.cpp +++ b/kdev-pg/kdev-pg-follow.cpp @@ -1,236 +1,236 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2006 Alexander Dymo Copyright (C) 2010 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-follow.h" #include "kdev-pg-pretty-printer.h" -#include +#include //uncomment this to see debug output for follow dependency calculation // #define followDepsEP_DEBUG /* * Computing LL(k)-follow-sets */ namespace KDevPG { extern QTextStream checkOut; #ifdef FOLLOWDEP_DEBUG void DebugFollowDep(Model::Node *dest, Model::Node *dep, const QString &message) { checkOut << "=============================" << endl; PrettyPrinter p(QTextStream( stderr )); checkOut << "adding " << message << " "; p(dep); checkOut << " (" << (uint*)dep << ")"; checkOut << " to follow "; p(dest); checkOut << " (" << (uint*)dest << ")"; checkOut << "{" << dest->kind << "}"; if (dest->kind == Model::Node_kind_nonTerminal) { Model::SymbolItem *s = ((Model::NonTerminalItem*)dest)->mSymbol; if (s) checkOut << "__"; p(s); checkOut << "__"; } checkOut << endl; } void debugFirstToFollowDep(Model::Node *dest, Model::Node *dep) { DebugFollowDep(dest, dep, "first"); } void debugFollowToFollowDep(Model::Node *dest, Model::Node *dep) { DebugFollowDep(dest, dep, "follow"); } #endif // // Calculating the FOLLOW set depends on the first set being already available // and is in principle quite easy. There are only a few simple rules: // // 1. Put EOF at the end of the start rule // 2. For every rule "items -> rulename", put FOLLOW(rulename) into FOLLOW(items) // 3. For every item sequence "item1 item2", put first(item2) into FOLLOW(item1) // 4. For every rule "item1 item2 -> rulename", put FOLLOW(rulename) // into FOLLOW(item1) if item2 can derive to epsilon ("0"). // 5. Propagate the FOLLOW sets down to the symbols where appropriate. // 6. Loop for all rules until there are no changes in any FOLLOW set anymore. // NextFollow::NextFollow(bool &changed) : mChanged(changed) { Model::TerminalItem *teof = globalSystem.pushTerminal("EOF", "end of file"); for(auto i = globalSystem.rules.begin(); i != globalSystem.rules.end(); ++i) { if(globalSystem.start.contains((*i)->mSymbol)) { globalSystem.follow(*i).insert(teof); globalSystem.follow((*i)->mSymbol).insert(teof); globalSystem.follow((*i)->mItem).insert(teof); } } } void NextFollow::operator()(Model::Node *node) { Model::EvolveItem *e = nodeCast(node); Q_ASSERT(e != nullptr); mSymbol = e->mSymbol; visitNode(node); } void NextFollow::merge(Model::Node*__dest, World::NodeSet const &source) { if (nodeCast(__dest) != nullptr || nodeCast(__dest) != nullptr) { return; } World::NodeSet &dest = globalSystem.follow(__dest); for (World::NodeSet::const_iterator it = source.begin(); it != source.end(); ++it) { if (Model::TerminalItem *t = nodeCast(*it)) { if( !dest.contains(t) ) { mChanged = true; dest.insert(t); } } } } void NextFollow::visitCons(Model::ConsItem *node) { merge(node->mRight, globalSystem.follow(node)); addFollowToFollowDep(node->mRight, node); merge(node->mLeft, globalSystem.first(node->mRight)); addFirstToFollowDep(node->mLeft, node->mRight); if (reducesToEpsilon(node->mRight)) { merge(node->mLeft, globalSystem.follow(node)); addFollowToFollowDep(node->mLeft, node); } DefaultVisitor::visitCons(node); } void NextFollow::visitAlternative(Model::AlternativeItem *node) { merge(node->mLeft, globalSystem.follow(node)); addFollowToFollowDep(node->mLeft, node); merge(node->mRight, globalSystem.follow(node)); addFollowToFollowDep(node->mRight, node); DefaultVisitor::visitAlternative(node); } void NextFollow::visitNode(Model::Node* node) { if(node == nullptr) return; if(mVisited.contains(node)) return; mVisited.insert(node); KDevPG::Visitor::visitNode(node); mVisited.remove(node); } void NextFollow::preCopy(Model::Node* from, Model::Node* to) { if(from != nullptr && to != nullptr) { merge(from, globalSystem.follow(to)); addFollowToFollowDep(from, to); } } void NextFollow::copy(Model::Node* from, Model::Node* to) { Q_UNUSED(from); Q_UNUSED(to); } void NextFollow::addFirstToFollowDep(Model::Node *dest, Model::Node *dep) { if (dest->kind == Model::NodeKindNonTerminal) { Model::SymbolItem *s = nodeCast(dest)->mSymbol; if (s) globalSystem.followDep(s).first.insert(dep); } else globalSystem.followDep(dest).first.insert(dep); #ifdef FOLLOWDEP_DEBUG debugFirstToFollowDep(dest, dep); #endif } void NextFollow::addFollowToFollowDep(Model::Node *dest, Model::Node *dep) { if (dest->kind == Model::NodeKindNonTerminal) { Model::SymbolItem *s = nodeCast(dest)->mSymbol; if (s) globalSystem.followDep(s).second.insert(dep); } else globalSystem.followDep(dest).second.insert(dep); #ifdef FOLLOWDEP_DEBUG debugFollowToFollowDep(dest, dep); #endif } void computeFollow() { bool changed = true; NextFollow next(changed); while (true) { for(QList::iterator it = globalSystem.rules.begin(); it != globalSystem.rules.end(); ++it) { next(*it); } if(!changed) // for the eof in the first iteration break; changed = false; } } } // kate: space-indent on; indent-width 2; tab-width 2; show-tabs on; diff --git a/kdev-pg/kdev-pg-generate.cpp b/kdev-pg/kdev-pg-generate.cpp index 2f8a8a0..a0f1747 100644 --- a/kdev-pg/kdev-pg-generate.cpp +++ b/kdev-pg/kdev-pg-generate.cpp @@ -1,874 +1,874 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-generate.h" #include "kdev-pg.h" #include "kdev-pg-code-gen.h" #include "kdev-pg-ast-gen.h" #include "kdev-pg-visitor-gen.h" #include "kdev-pg-visitor-bits-gen.h" #include "kdev-pg-default-visitor-gen.h" #include "kdev-pg-default-visitor-bits-gen.h" #include "kdev-pg-serialize-visitor-gen.h" #include "kdev-pg-debug-visitor-gen.h" #include "kdev-pg-new-visitor-gen.h" #include "kdev-pg-new-visitor-bits-gen.h" #include "kdev-pg-beautifier.h" #include "kdev-pg-regexp.h" -#include -#include +#include +#include #include "kdev-pg-token-type-gen.h" namespace KDevPG { void generateOutput() { QByteArray language = globalSystem.language.toUpper().toLatin1(); for(int i = 0; i != language.size(); ++i) { if(language[i] < '0' || (language[i] > '9' && language[i] < 'A') || language[i] > 'Z') language[i] = '_'; } if (globalSystem.generateAst) { { // generate the ast QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateAst _Ast(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_AST_H_INCLUDED" << endl << "#define " << language << "_AST_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "ast-fwd.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; foreach (const QString& header, globalSystem.astHeaders) s << "#include \"" << header << "\"\n"; - s << "#include " << endl + s << "#include " << endl << "#include " << endl << endl; if (!globalSystem.decl.isEmpty()) s << globalSystem.decl << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; _Ast(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "ast.h"; format(s, oname); } { // generate ast forward declarations QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateAstFwd _AstFwd(s); s << ""// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_AST_FWD_INCLUDED" << endl << "#define " << language << "_AST_FWD_INCLUDED" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; _AstFwd(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "ast-fwd.h"; format(s, oname); } } { // generate token type QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateTokenType gen(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_TOKEN_TYPE_H_INCLUDED" << endl << "#define " << language << "_TOKEN_TYPE_H_INCLUDED" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; foreach (const QString& header, globalSystem.astHeaders) s << "#include \"" << header << "\"\n"; if (!globalSystem.decl.isEmpty()) s << globalSystem.decl << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; gen(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "tokentype.h"; format(s, oname); } { // generate the parser decls QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateParserDeclarations __decls(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_H_INCLUDED" << endl << "#define " << language << "_H_INCLUDED" << endl << endl; s << "#include \"" << globalSystem.language << "tokentype.h\"" << endl; if(globalSystem.hasLexer) s << "#include \"" << globalSystem.language << "lexer.h\"" << endl; if (globalSystem.generateAst) { s << "#include \"" << globalSystem.language << "ast-fwd.h\"" << endl << "#include " << endl << "#include " << endl; } if (globalSystem.tokenStream == "KDevPG::TokenStream") s << "#include " << endl; foreach (const QString& header, globalSystem.parserDeclarationHeaders) s << "#include \"" << header << "\"\n"; s << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; if (globalSystem.needOperatorStack) - s << "#include " << endl; + s << "#include " << endl; if (!globalSystem.decl.isEmpty() && !globalSystem.generateAst) s << globalSystem.decl << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; __decls(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "parser.h"; format(s, oname); } if (globalSystem.generateAst) { // generate the visitor decls QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateVisitor __visitor(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_VISITOR_H_INCLUDED" << endl << "#define " << language << "_VISITOR_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "ast.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; __visitor(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "visitor.h"; format(s, oname); } if (globalSystem.generateAst) { // generate the default visitor QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateDefaultVisitor __DefaultVisitor(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_DEFAULT_VISITOR_H_INCLUDED" << endl << "#define " << language << "_DEFAULT_VISITOR_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "visitor.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; __DefaultVisitor(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "defaultvisitor.h"; format(s, oname); } if (globalSystem.generateSerializeVisitor) { // generate the serialization visitor QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateSerializeVisitor __serialize_visitor(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_SERIALIZATION_H_INCLUDED" << endl << "#define " << language << "_SERIALIZATION_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "defaultvisitor.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; - s << "#include " << endl - << "#include " << endl + s << "#include " << endl + << "#include " << endl << endl << "namespace " << globalSystem.ns << "{" << endl << endl; __serialize_visitor(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; s << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "serializevisitor.h"; format(s, oname); } if (globalSystem.generateDebugVisitor) { // generate the debug visitor QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateDebugVisitor __debug_visitor(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_DEBUG_VISITOR_H_INCLUDED" << endl << "#define " << language << "_DEBUG_VISITOR_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "defaultvisitor.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "#include " << endl; - s << "#include " << endl - << "#include " << endl + s << "#include " << endl + << "#include " << endl << endl << "namespace " << globalSystem.ns << "{" << endl << endl; __debug_visitor(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; s << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "debugvisitor.h"; format(s, oname); } if (globalSystem.generateTokenText || globalSystem.generateDebugVisitor) { // generate the token text function QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_TOKEN_TEXT_H_INCLUDED" << endl << "#define " << language << "_TOKEN_TEXT_H_INCLUDED" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "#include \"" << globalSystem.language << "tokentype.h\"" << endl << "namespace " << globalSystem.ns << "{" << endl << endl << "QString tokenText(int token)" << endl << "{" << endl; GenerateTokenTexts gen(s); gen(); s << "}" << endl << "} // end of namespace " << globalSystem.ns << endl << endl; s << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "tokentext.h"; format(s, oname); } { // generate the parser bits QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateParserBits __bits(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl; s << "#include \"" << globalSystem.language << "parser.h\"" << endl; if (globalSystem.generateAst) { s << "#include \"" << globalSystem.language << "ast.h\"" << endl; } foreach (const QString& header, globalSystem.parserBitsHeaders) s << "#include \"" << header << "\"\n"; s << endl; if (!globalSystem.bits.isEmpty()) s << globalSystem.bits << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; __bits(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; QString oname = globalSystem.language; oname += "parser.cpp"; format(s, oname); } if (globalSystem.generateAst) { // generate the visitor bits QString str; QTextStream s(&str, QIODevice::WriteOnly); GenerateVisitorBits __visitor_bits(s); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#include \"" << globalSystem.language << "visitor.h\"" << endl << endl << "namespace " << globalSystem.ns << "{" << endl << endl; __visitor_bits(); s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; QString oname = globalSystem.language; oname += "visitor.cpp"; format(s, oname); } if (globalSystem.generateAst) { // generate the default visitor bits QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#include \"" << globalSystem.language << "defaultvisitor.h\"" << endl << endl << "namespace " << globalSystem.ns << "{" << endl << endl; GenerateDefaultVisitorBitsRule gen(s); for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it ) { gen(qMakePair(it.key(), *it)); } s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; QString oname = globalSystem.language; oname += "defaultvisitor.cpp"; format(s, oname); } } void generateLexer() { QByteArray language = globalSystem.language.toUpper().toLatin1(); bool hasStates = globalSystem.lexerEnvs.size() > 1; { // generate the lexer header QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#ifndef " << language << "_LEXER_H_INCLUDED" << endl << "#define " << language << "_LEXER_H_INCLUDED" << endl << endl << "#include \"" << globalSystem.language << "tokentype.h\"" << endl << endl << "#include " << endl << "#include " << endl << endl; foreach (const QString& header, globalSystem.lexerDeclarationHeaders) s << "#include \"" << header << "\"\n"; s << endl << "namespace " << globalSystem.ns << "{" << endl << endl << "class " << globalSystem.exportMacro << " " << globalSystem.tokenStream << " : " << (globalSystem.lexerBaseClass.isEmpty() ? QString() : " public " + globalSystem.lexerBaseClass + ",") << "public " << globalSystem.inputStream << "," << "public TokenTypeWrapper" << endl << "{" << endl << "public:" << endl << "typedef " << (globalSystem.lexerBaseClass.isEmpty() ? globalSystem.tokenStream : globalSystem.lexerBaseClass) << " Base;" << endl << "typedef " << globalSystem.inputStream << " Iterator;" << endl << endl << "private:" << endl; if(hasStates) { foreach(QString state, globalSystem.lexerEnvs.keys()) s << "Base::Token& lex" << KDevPG::capitalized(state) << "();" << endl; s << "public:\nenum RuleSet {\n"; foreach(QString state, globalSystem.lexerEnvs.keys()) s << "State_" << state << ", /*" << globalSystem.lexerEnvs[state].size() << "*/" << endl; s << "State_COUNT\n};\n" "private:\n" "RuleSet m_ruleSet;\n" "public:\n" "inline RuleSet ruleSet()\n{\nreturn m_ruleSet;\n}\n" "void setRuleSet(RuleSet rs);\n"; foreach(QString state, globalSystem.lexerEnvs.keys()) { s << "inline void enteringRuleSet" << state << "();" << endl; s << "inline void leavingRuleSet" << state << "();" << endl; } } s << "Iterator::PlainIterator spos;" << endl << "bool continueLexeme;" << endl << endl << "public:" << endl << globalSystem.tokenStream << "(const Iterator& iter);" << endl // non-virtual, virtuality will be inherited << "~" << globalSystem.tokenStream << "();" << endl << "Base::Token& read();" << endl; /// TODO: not good that it happens in a separate file for the parser but in this file for the lexer #define LEXER_EXTRA_CODE_GEN(name) \ if (globalSystem.lexerclassMembers.name.empty() == false) \ { \ s << "\n// user defined code:" << endl; \ GenerateMemberCode gen(s, Settings::MemberItem::PublicDeclaration \ | Settings::MemberItem::ProtectedDeclaration \ | Settings::MemberItem::PrivateDeclaration \ | Settings::MemberItem::ConstructorCode \ | Settings::MemberItem::DestructorCode); \ for( auto it = globalSystem.lexerclassMembers.name.begin(); \ it != globalSystem.lexerclassMembers.name.end(); ++it ) \ { \ gen(*it); \ } \ } LEXER_EXTRA_CODE_GEN(declarations) s << "};" << endl << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += "lexer.h"; format(s, oname); } { // generate the lexer bits QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "// THIS FILE IS GENERATED" << endl << "// WARNING! All changes made in this file will be lost!" << endl << endl << "#include \"" << globalSystem.language << "lexer.h\"" << endl << endl; foreach (const QString& header, globalSystem.lexerBitsHeaders) s << "#include \"" << header << "\"\n"; s << "\n#include \n"; s << endl << "namespace " << globalSystem.ns << "{" << endl << endl << globalSystem.tokenStream << "::" << globalSystem.tokenStream << "(const " << globalSystem.tokenStream << "::Iterator& iter) : Base(), Iterator(iter), " << (hasStates ? "m_ruleSet(State_start), " : "") << "continueLexeme(false)" << endl << "{"; LEXER_EXTRA_CODE_GEN(constructorCode) s << "}" << endl << endl << globalSystem.tokenStream << "::~" << globalSystem.tokenStream << "()\n{"; LEXER_EXTRA_CODE_GEN(destructorCode) s << "}" << endl << endl << "#define PP_CONCAT_IMPL(x, y) x ## y\n" // necessary, otherwise CURRENT_RULE_SET would not get resolved "#define PP_CONCAT(x, y) PP_CONCAT_IMPL(x, y)\n\n" "#define lxCURR_POS (Iterator::plain())\n" "#define lxCURR_IDX (Iterator::plain() - Iterator::begin())\n" "#define lxCONTINUE {continueLexeme = true; return read();}\n" "#define lxLENGTH (Iterator::plain() - Iterator::begin())\n" "#define lxBEGIN_POS (spos)\n" "#define lxBEGIN_IDX (spos - Iterator::begin())\n" "#define lxNAMED_TOKEN(token, X) KDevPG::Token& token(Base::push()); token.kind = Token_##X; token.begin = lxBEGIN_IDX; token.end = lxCURR_IDX - 1;\n" "#define lxTOKEN(X) {lxNAMED_TOKEN(token, X);}\n" "#define lxDONE {return Base::read();}\n" "#define lxRETURN(X) {lxTOKEN(X); lxDONE}\n" "#define lxEOF {Base::Token& _t(Base::push()); _t.kind = Token_EOF;_t.begin = _t.end = Iterator::plain() - Iterator::begin();}\n" "#define lxFINISH {lxEOF lxDONE}\n" "#define yytoken (Base::back())\n" "#define lxFAIL {goto _fail;}\n" "#define lxSKIP {return read();}\n" "#define lxNEXT_CHR(chr) { if(!Iterator::hasNext()) goto _end; chr = Iterator::next(); }\n" << endl; if(hasStates) { s << "#define lxSET_RULE_SET(r) {PP_CONCAT(leavingRuleSet, CURRENT_RULE_SET) (); m_ruleSet = State_##r; enteringRuleSet##r ();}\n" << endl << endl; foreach(QString state, globalSystem.lexerEnvs.keys()) { s << "inline void " << globalSystem.tokenStream << "::enteringRuleSet" << state << "() { " << globalSystem.enteringCode[state] << "}" << endl; s << "inline void " << globalSystem.tokenStream << "::leavingRuleSet" << state << "() { " << globalSystem.leavingCode[state] << "}" << endl; } s << "\n" "void " << globalSystem.tokenStream << "::setRuleSet(RuleSet rs)\n" "{\n" "switch(m_ruleSet)\n" "{\n"; foreach(QString state, globalSystem.lexerEnvs.keys()) { s << "case State_" << state << ":\n" "leavingRuleSet" << state << "();\n" "break;\n"; } s << "\ndefault:\n" "assert(0 == \"Invalid rule set\");\n" "}\n\n" "m_ruleSet = rs;\n\n" "switch(m_ruleSet)\n" "{\n"; foreach(QString state, globalSystem.lexerEnvs.keys()) { s << "case State_" << state << ":\n" "enteringRuleSet" << state << "();\n" "break;\n"; } s << "\ndefault:\n" "assert(0 == \"Invalid rule set\");\n" "}\n" "}\n\n"; } #define LEXER_CORE_IMPL(name, state, extra) \ s << globalSystem.tokenStream << "::Base::Token& " << globalSystem.tokenStream << "::" \ << name << "()" << endl << "{" \ << extra << "if(!Iterator::hasNext())\n{\nlxFINISH\n}" << endl \ << "if(continueLexeme) continueLexeme = false;\nelse spos = plain();\nIterator::PlainIterator lpos = Iterator::plain();\nIterator::Int chr = 0;\nint lstate = 0;\n"; \ globalSystem.dfaForNfa[globalSystem.lexerEnvResults[state]]->codegen(s); \ s << "/* assert(false);*/\nreturn Base::read();}" << endl << endl; if(hasStates) { foreach(QString state, globalSystem.lexerEnvs.keys()) { s << "#define CURRENT_RULE_SET " << state << endl; LEXER_CORE_IMPL("lex" + KDevPG::capitalized(state), state, "") s << "#undef CURRENT_RULE_SET" << endl; } s << globalSystem.tokenStream << "::Base::Token& " << globalSystem.tokenStream << "::read()" << endl << "{" << endl << "if(Base::index() < Base::size())\nreturn Base::read();\nswitch(m_ruleSet)\n{" << endl; foreach(QString state, globalSystem.lexerEnvs.keys()) s << "case State_" << state << ": return lex" << capitalized(state) << "();" << endl; s << "default:\nexit(-1);\n}\n}" << endl; } else { LEXER_CORE_IMPL("read", "start", "if(Base::index() < Base::size())\nreturn Base::read();\n") } s << globalSystem.lexerBits << endl; if(hasStates) { s << "#undef lxSET_RULE_SET\n" << endl; } s << "#undef lxNEXT_CHR\n" "#undef lxFAIl\n" "#undef lxRETURN\n" "#undef lxTOKEN\n" "#undef lxBEGIN_IDX\n" "#undef lxBEGIN_POS\n" "#undef lxLENGTH\n" "#undef lxCONTINUE\n" "#undef lxCURR_IDX\n" "#undef lxCURR_POS\n\n" "#undef PP_CONCAT\n" "#undef PP_CONCAT_IMPL\n" << endl; s << "} // end of namespace " << globalSystem.ns << endl << endl; QString oname = globalSystem.language; oname += "lexer.cpp"; format(s, oname); } } void generateVisitor(const QString& name, bool inherit_default) { QByteArray language = globalSystem.language.toUpper().toLatin1(); for(int i = 0; i != language.size(); ++i) { if(language[i] < '0' || (language[i] > '9' && language[i] < 'A') || language[i] > 'Z') language[i] = '_'; } QByteArray upper_name = name.toUpper().toLatin1(); { QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "#ifndef " << language << "_" << upper_name << "_H" << endl << "#define " << language << "_" << upper_name << "_H" << endl << endl << "#include \"" << globalSystem.language << (inherit_default ? "default" : "") << "visitor.h\"" << endl << endl; if (!globalSystem.exportMacroHeader.isEmpty()) s << "#include \"" << globalSystem.exportMacroHeader << "\"" << endl; s << "namespace " << globalSystem.ns << "{" << endl << endl; if (inherit_default) { // generate an empty visitor using the default-visitor GenerateNewVisitor visitor(s, name); visitor(); } else { // generate a visitor like the default visitor GenerateDefaultVisitor visitor(s, name); visitor(); } s << endl << "} // end of namespace " << globalSystem.ns << endl << endl << "#endif" << endl << endl; QString oname = globalSystem.language; oname += name.toLower() + ".h"; format(s, oname); } { QString str; QTextStream s(&str, QIODevice::WriteOnly); s << "#include \"" << globalSystem.language << "defaultvisitor.h\"" << endl << endl << "namespace " << globalSystem.ns << "{" << endl << endl; if(inherit_default) { GenerateNewVisitorBitsRule gen(s, name); for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it ) { gen(qMakePair(it.key(), *it)); } } else { GenerateDefaultVisitorBitsRule gen(s, name); for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); it != globalSystem.symbols.end(); ++it ) { gen(qMakePair(it.key(), *it)); } } s << endl << "} // end of namespace " << globalSystem.ns << endl << endl; QString oname = globalSystem.language; oname += name.toLower() + ".cpp"; format(s, oname); } } } diff --git a/kdev-pg/kdev-pg-lexer.cc b/kdev-pg/kdev-pg-lexer.cc index 63a82f6..39d1a2c 100644 --- a/kdev-pg/kdev-pg-lexer.cc +++ b/kdev-pg/kdev-pg-lexer.cc @@ -1,3483 +1,3483 @@ #line 2 "kdev-pg-lexer.cc" #line 4 "kdev-pg-lexer.cc" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 1 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yynoreturn yy_fatal_error (yyconst char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ (yytext_ptr) -= (yy_more_len); \ yyleng = (int) (yy_cp - (yytext_ptr)); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 139 #define YY_END_OF_BUFFER 140 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_acclist[518] = { 0, 1, 1, 131, 131, 59, 59, 107, 107, 110, 110, 126, 126, 140, 138, 139, 1, 138, 139, 2, 139, 2, 138, 139, 138, 139, 13, 138, 139, 138, 139, 22, 138, 139, 7, 138, 139, 8, 138, 139, 18, 138, 139, 17, 138, 139, 11, 138, 139, 138, 139, 14, 138, 139, 12, 136, 138, 139, 136, 138, 139, 15, 138, 139, 4, 138, 139, 16, 138, 139, 19, 138, 139, 20, 138, 139, 134, 135, 138, 139, 71, 138, 139, 135, 138, 139, 135, 138, 139, 135, 138, 139, 9, 138, 139, 21, 138, 139, 10, 138, 139, 131, 139, 130, 139, 130, 139, 132, 139, 70, 139, 59, 70, 139, 60, 139, 60, 70, 139, 61, 70, 139, 69, 70, 139, 70, 139, 70, 139, 70, 139, 70, 139, 107, 139, 104, 139, 104, 139, 106, 139, 108, 139, 109, 139, 124, 139, 110, 124, 139, 111, 139, 111, 124, 139, 114, 124, 139, 124, 139, 122, 124, 139, 113, 124, 139, 121, 124, 139, 122, 124, 139, 123, 124, 139, 122, 124, 139, 122, 124, 139, 122, 124, 139, 122, 124, 139, 122, 124, 139, 126, 128, 139, 125, 139, 125, 128, 139, 127, 128, 139, 139, 102, 139, 73, 139, 73, 139, 139, 139, 85, 139, 79, 139, 80, 139, 87, 139, 88, 139, 139, 90, 139, 101, 139,16484, 76, 139, 81, 139, 89, 139, 101, 139,16483,16484, 77, 139, 139, 78, 139, 83, 139, 139, 82, 139, 86, 139, 1, 2, 137, 52, 53, 3, 5, 6, 136, 4, 135, 134, 135, 129, 135, 135, 131, 130, 132, 132, 133, 59, 60, 107, 104, 105, 110, 111, 112, 122, 113, 122, 122, 122, 122, 122, 122, 122, 126, 125, 73, 103, 72, 91, 101,16484, 8292,16459, 76, 8291, 8292, 101,16483, 16484, 98, 101, 101, 101, 101, 101, 137, 3, 135, 135, 105, 112, 122, 122, 122, 122, 122, 122, 103, 97, 96, 72, 84, 101, 101, 101, 101, 101, 8267, 101, 101, 101, 101, 74, 46, 47, 135, 68, 122, 122, 118, 122, 122, 122, 122, 84, 84, 84, 84, 101, 101, 101, 101, 101, 101, 101, 101, 54, 48, 49, 25, 135, 122, 122, 122, 119, 122, 122, 93, 84, 84, 84, 84, 101, 101, 101, 101, 101, 101, 101, 58, 50, 55, 28, 62, 122, 115, 122, 122, 122, 94, 95, 84, 84, 84, 84, 101, 101, 101, 101, 101, 101, 56, 63, 122, 122, 122, 84, 84, 84, 101, 101, 101, 101, 101, 101, 57, 117, 122, 122, 120, 122, 84, 84, 84, 101, 101, 101, 101, 101, 101, 43, 51, 64, 116, 122, 92, 84, 84, 84, 101, 101, 101, 101, 101, 30, 67, 84, 84, 101, 101, 101, 37, 45, 32, 23, 66, 65, 84, 84, 101, 101, 44, 31, 41, 24, 84, 101, 101, 26, 33, 29, 84, 101, 101, 84, 101, 101, 40, 42, 84, 101, 101, 84, 101, 101, 84, 101, 101, 34, 39, 84, 101, 101, 36, 84, 101, 101, 27, 84, 101, 101, 84, 101, 101, 84, 101, 101, 84, 101, 101, 84, 101, 38, 84, 35 } ; static yyconst flex_int16_t yy_accept[670] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 16, 19, 21, 24, 26, 29, 31, 34, 37, 40, 43, 46, 49, 51, 54, 58, 61, 64, 67, 70, 73, 76, 80, 83, 86, 89, 92, 95, 98, 101, 103, 105, 107, 109, 111, 114, 116, 119, 122, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 150, 152, 155, 158, 160, 163, 166, 169, 172, 175, 178, 181, 184, 187, 190, 193, 195, 198, 201, 202, 204, 206, 208, 209, 210, 212, 214, 216, 218, 220, 221, 223, 226, 228, 230, 232, 236, 238, 239, 241, 243, 244, 246, 248, 249, 250, 250, 251, 251, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 255, 256, 257, 258, 259, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 271, 271, 271, 271, 271, 272, 273, 273, 274, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 289, 290, 290, 290, 290, 290, 290, 290, 291, 292, 292, 292, 294, 295, 295, 296, 296, 297, 297, 299, 302, 303, 304, 305, 306, 307, 308, 308, 308, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 310, 311, 312, 312, 312, 312, 312, 312, 312, 312, 312, 313, 313, 314, 315, 316, 317, 318, 319, 320, 320, 321, 321, 322, 322, 322, 322, 323, 323, 324, 325, 325, 326, 327, 328, 329, 330, 331, 331, 332, 333, 334, 335, 335, 336, 336, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 338, 338, 338, 338, 338, 338, 338, 339, 339, 340, 340, 340, 340, 340, 340, 340, 341, 342, 344, 345, 346, 347, 347, 347, 347, 347, 348, 349, 350, 351, 352, 353, 354, 355, 355, 356, 357, 358, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 360, 361, 361, 361, 361, 361, 362, 362, 364, 364, 364, 364, 364, 364, 364, 364, 365, 366, 367, 369, 370, 370, 370, 371, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 382, 382, 382, 382, 382, 382, 382, 383, 383, 384, 384, 384, 385, 385, 385, 386, 386, 386, 386, 386, 386, 386, 386, 387, 388, 390, 391, 392, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 404, 404, 404, 404, 404, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 406, 406, 407, 408, 409, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 418, 418, 418, 418, 418, 418, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 421, 422, 424, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 435, 435, 435, 435, 435, 435, 435, 435, 435, 436, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 449, 450, 451, 452, 453, 454, 454, 455, 455, 455, 455, 456, 456, 456, 457, 457, 457, 457, 457, 457, 457, 457, 458, 458, 459, 460, 461, 462, 463, 464, 464, 464, 464, 464, 464, 464, 465, 465, 465, 466, 466, 467, 467, 468, 469, 470, 471, 471, 472, 472, 473, 473, 473, 473, 473, 473, 474, 475, 476, 477, 477, 477, 477, 477, 477, 477, 477, 477, 478, 479, 480, 480, 480, 481, 481, 481, 481, 481, 482, 483, 484, 485, 485, 485, 485, 485, 485, 485, 486, 487, 488, 488, 488, 488, 488, 488, 488, 489, 490, 491, 492, 492, 493, 493, 493, 493, 494, 495, 496, 496, 496, 497, 497, 498, 499, 500, 501, 501, 501, 502, 503, 504, 504, 504, 505, 506, 507, 507, 507, 508, 509, 510, 510, 510, 511, 512, 513, 513, 513, 514, 515, 516, 516, 517, 518, 518 } ; static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 6, 9, 10, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 30, 31, 30, 30, 32, 32, 32, 32, 32, 33, 32, 32, 34, 32, 32, 35, 32, 32, 36, 32, 32, 36, 37, 32, 38, 39, 40, 41, 42, 6, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 52, 65, 66, 52, 67, 68, 69, 70, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst YY_CHAR yy_meta[71] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 8, 8, 8, 8, 9, 10, 5, 5, 5, 5, 5, 11, 11, 12, 12, 12, 12, 12, 12, 6, 13, 6, 5, 12, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 5, 5, 14, 5 } ; static yyconst flex_uint16_t yy_base[704] = { 0, 0, 0, 68, 70, 73, 77, 92, 98, 138, 0, 83, 100, 208, 0, 1820, 1821, 92, 1821, 1816, 76, 1821, 254, 1821, 1821, 1821, 1821, 1821, 1821, 82, 1792, 91, 106, 1821, 1793, 1821, 1821, 1821, 252, 1793, 0, 1772, 1754, 1821, 1821, 1821, 0, 1821, 1810, 93, 1821, 132, 1821, 1809, 1821, 1821, 1760, 1753, 1762, 230, 0, 1821, 1805, 284, 1821, 1821, 1821, 290, 1821, 1804, 1821, 1790, 0, 294, 1821, 298, 1821, 305, 309, 313, 317, 323, 0, 1821, 1802, 1821, 1821, 1821, 1821, 1801, 302, 259, 1821, 1821, 1821, 1821, 1821, 284, 1821, 344, 373, 1821, 1821, 396, 1780, 348, 1821, 1821, 0, 1821, 1821, 348, 1821, 315, 1821, 333, 1821, 1821, 1741, 1750, 1735, 296, 1752, 1755, 330, 1746, 1749, 312, 0, 1821, 1821, 387, 1771, 0, 409, 1821, 1732, 1727, 0, 1821, 340, 348, 1821, 356, 1821, 1730, 1735, 45, 57, 1746, 0, 1821, 379, 1821, 384, 390, 1821, 0, 0, 391, 428, 433, 437, 441, 445, 449, 453, 0, 1821, 1821, 395, 1821, 397, 1746, 1731, 1731, 1743, 372, 0, 1821, 474, 1746, 481, 1821, 470, 506, 1768, 521, 491, 1821, 1767, 1821, 464, 522, 530, 554, 538, 1713, 482, 492, 521, 1719, 1724, 1721, 1720, 389, 464, 1722, 1716, 1714, 370, 1725, 1714, 1728, 1711, 1717, 0, 1724, 1750, 1706, 1705, 1711, 1702, 1699, 1700, 1707, 525, 527, 532, 0, 559, 567, 584, 588, 593, 597, 533, 552, 555, 1821, 1704, 1697, 1707, 1821, 1714, 0, 1821, 590, 475, 613, 622, 646, 644, 1732, 514, 659, 666, 687, 680, 1686, 1821, 1712, 1821, 1696, 1689, 1704, 1699, 1687, 1701, 1700, 320, 1684, 1821, 1688, 1694, 1680, 1688, 1685, 1693, 1689, 1678, 1821, 1675, 1693, 1675, 1691, 1686, 1681, 682, 650, 691, 701, 705, 719, 1669, 1683, 1675, 1664, 723, 630, 0, 528, 730, 744, 765, 737, 549, 751, 758, 795, 782, 744, 1667, 1664, 1677, 1675, 1821, 1663, 1661, 1665, 1673, 1821, 1659, 1656, 1670, 1669, 1821, 1659, 0, 508, 1654, 1653, 1649, 1649, 1665, 1664, 784, 808, 813, 825, 830, 1657, 1647, 1821, 1659, 834, 638, 0, 548, 841, 850, 871, 856, 865, 901, 887, 1662, 1639, 1656, 1640, 1659, 1638, 1649, 550, 1640, 1821, 1637, 1645, 1821, 1639, 1652, 1651, 1647, 1637, 1627, 1646, 1643, 1640, 1624, 1821, 877, 889, 908, 915, 1629, 1821, 1821, 919, 695, 0, 563, 934, 955, 941, 943, 985, 951, 1623, 1621, 1639, 1639, 576, 1821, 1592, 444, 1597, 1607, 583, 1583, 1599, 1573, 1565, 1556, 1545, 1540, 1509, 1495, 1821, 1496, 972, 989, 998, 1462, 1002, 0, 625, 1019, 1040, 1027, 1034, 1070, 1056, 1475, 1461, 1460, 1444, 1436, 1425, 1821, 49, 1439, 1439, 1436, 722, 1414, 1391, 1407, 1393, 1370, 1362, 1377, 1358, 1356, 1290, 1300, 1058, 1077, 1083, 1298, 1087, 0, 654, 1103, 1125, 1110, 1112, 720, 1119, 1821, 1301, 1296, 1299, 1296, 1279, 1276, 1274, 1290, 1273, 1286, 704, 1284, 1287, 1821, 1285, 1258, 1262, 1264, 1267, 1242, 1241, 1227, 1821, 1140, 1821, 1144, 0, 709, 1158, 783, 1165, 784, 1167, 1244, 1215, 1229, 1206, 1215, 1204, 1189, 1190, 1178, 1821, 1177, 1165, 1181, 1164, 1170, 1173, 1171, 1154, 1167, 1143, 1144, 1821, 1169, 761, 820, 1176, 1182, 1144, 1821, 1134, 1147, 1139, 1821, 1134, 1132, 1821, 1120, 1091, 1094, 1080, 1089, 1067, 1078, 1821, 1067, 1821, 1821, 1821, 773, 1189, 1191, 1065, 1054, 1059, 1039, 1043, 1022, 1821, 1039, 1031, 1821, 1004, 1821, 1008, 1821, 799, 1197, 1203, 1002, 1010, 988, 1821, 995, 984, 964, 937, 925, 1821, 845, 1213, 1215, 924, 902, 856, 857, 832, 841, 836, 807, 858, 1221, 1227, 811, 801, 1821, 791, 773, 777, 745, 1821, 863, 1229, 1237, 729, 739, 728, 697, 702, 644, 893, 1239, 1245, 627, 638, 594, 583, 583, 563, 905, 1251, 1253, 1821, 549, 1821, 548, 503, 500, 923, 1261, 1263, 459, 431, 1821, 395, 959, 1269, 1275, 1821, 378, 366, 964, 1277, 1285, 367, 356, 968, 1287, 1293, 316, 308, 976, 1299, 1301, 274, 256, 993, 1309, 942, 220, 82, 1006, 950, 1821, 60, 1821, 1821, 1821, 1348, 1362, 1376, 1390, 1404, 1411, 1423, 1437, 1451, 1465, 1472, 1477, 1489, 1503, 1516, 1526, 1025, 1540, 1554, 1568, 1582, 1596, 1610, 1617, 1627, 1635, 1641, 1652, 1666, 1040, 1056, 1057, 1129, 1142, 1146 } ; static yyconst flex_int16_t yy_def[704] = { 0, 668, 1, 669, 669, 670, 670, 671, 671, 668, 9, 672, 672, 668, 13, 668, 668, 668, 668, 668, 673, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 674, 668, 674, 674, 674, 668, 668, 668, 675, 668, 668, 676, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 677, 668, 668, 678, 668, 668, 668, 668, 668, 668, 668, 668, 679, 668, 668, 680, 668, 680, 680, 680, 680, 680, 681, 668, 668, 668, 668, 668, 668, 668, 682, 668, 668, 668, 668, 668, 668, 668, 668, 683, 668, 668, 668, 683, 668, 684, 668, 668, 685, 668, 668, 668, 668, 673, 668, 686, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 687, 668, 668, 668, 668, 674, 674, 668, 674, 674, 675, 668, 676, 676, 668, 668, 668, 668, 668, 668, 668, 668, 677, 668, 678, 668, 688, 668, 668, 689, 679, 668, 680, 680, 680, 680, 680, 680, 680, 681, 668, 668, 682, 668, 690, 668, 668, 668, 668, 668, 691, 668, 668, 692, 683, 668, 693, 668, 668, 668, 668, 668, 103, 668, 694, 694, 694, 694, 694, 695, 673, 673, 686, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 687, 674, 674, 668, 668, 668, 668, 668, 668, 668, 678, 678, 688, 689, 680, 680, 680, 680, 680, 680, 682, 682, 690, 668, 668, 668, 668, 668, 668, 691, 668, 696, 694, 694, 694, 195, 694, 668, 697, 694, 694, 195, 694, 695, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 674, 668, 668, 668, 668, 668, 668, 668, 668, 680, 680, 680, 680, 680, 680, 668, 668, 668, 668, 668, 668, 698, 668, 694, 694, 251, 694, 697, 694, 694, 195, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 674, 668, 668, 668, 668, 668, 668, 668, 680, 680, 680, 680, 680, 668, 668, 668, 668, 668, 668, 699, 668, 694, 694, 251, 694, 694, 195, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 680, 680, 680, 680, 668, 668, 668, 668, 668, 700, 668, 694, 251, 694, 694, 195, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 680, 680, 680, 668, 668, 701, 668, 694, 251, 694, 694, 195, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 680, 680, 680, 668, 668, 702, 668, 694, 251, 694, 694, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 680, 668, 668, 703, 668, 694, 694, 694, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 668, 694, 694, 668, 668, 668, 668, 694, 694, 668, 668, 668, 694, 694, 668, 668, 668, 694, 694, 668, 668, 668, 694, 694, 668, 668, 668, 694, 668, 668, 668, 668, 0, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668 } ; static yyconst flex_uint16_t yy_nxt[1892] = { 0, 16, 17, 18, 19, 17, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 31, 32, 32, 32, 33, 34, 16, 35, 16, 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, 39, 16, 16, 16, 38, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 40, 40, 40, 40, 43, 44, 45, 16, 47, 48, 47, 48, 51, 52, 53, 51, 51, 52, 53, 51, 114, 54, 55, 83, 84, 54, 55, 221, 49, 474, 49, 111, 61, 62, 111, 128, 63, 475, 61, 62, 83, 84, 63, 222, 85, 223, 129, 131, 131, 131, 131, 224, 115, 141, 56, 57, 58, 667, 56, 57, 58, 85, 131, 131, 131, 131, 665, 64, 59, 65, 142, 143, 59, 64, 143, 65, 66, 67, 68, 69, 67, 66, 66, 70, 66, 66, 66, 66, 66, 66, 66, 71, 66, 66, 72, 72, 72, 72, 73, 74, 66, 66, 66, 66, 66, 75, 75, 75, 75, 75, 75, 75, 75, 66, 66, 76, 66, 75, 77, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 78, 79, 75, 75, 75, 75, 75, 80, 75, 81, 75, 75, 66, 66, 66, 66, 86, 87, 88, 89, 87, 86, 90, 86, 91, 92, 93, 94, 95, 96, 86, 97, 98, 86, 99, 99, 99, 99, 86, 100, 86, 86, 86, 101, 102, 103, 103, 103, 103, 103, 103, 103, 103, 104, 105, 106, 107, 103, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 108, 109, 86, 110, 116, 664, 117, 134, 134, 134, 134, 134, 134, 134, 134, 148, 153, 155, 149, 134, 155, 159, 118, 119, 159, 178, 120, 661, 173, 174, 121, 175, 176, 122, 171, 123, 179, 124, 177, 125, 126, 127, 158, 158, 158, 158, 660, 114, 154, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 199, 172, 158, 158, 158, 158, 180, 180, 180, 180, 111, 656, 204, 111, 115, 213, 162, 205, 143, 214, 181, 143, 655, 668, 164, 161, 166, 319, 183, 215, 163, 141, 200, 208, 165, 185, 185, 185, 185, 193, 668, 320, 194, 184, 195, 196, 153, 209, 668, 186, 210, 227, 155, 159, 193, 155, 159, 187, 188, 188, 188, 188, 171, 651, 237, 194, 131, 131, 131, 131, 650, 195, 181, 195, 196, 243, 646, 272, 154, 244, 189, 273, 265, 228, 266, 645, 190, 190, 190, 190, 190, 190, 190, 190, 172, 184, 238, 641, 190, 134, 134, 134, 134, 134, 134, 134, 134, 158, 158, 158, 158, 134, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 180, 180, 180, 180, 181, 640, 230, 180, 180, 180, 180, 232, 439, 114, 440, 668, 231, 188, 188, 188, 188, 668, 183, 114, 233, 249, 234, 184, 250, 183, 251, 252, 185, 185, 185, 185, 267, 235, 184, 189, 249, 185, 185, 639, 184, 115, 186, 185, 185, 185, 185, 250, 199, 268, 253, 115, 153, 251, 153, 251, 252, 186, 181, 227, 171, 255, 255, 255, 255, 187, 181, 348, 348, 256, 256, 256, 185, 185, 181, 372, 635, 258, 258, 171, 200, 184, 237, 634, 154, 373, 154, 390, 390, 184, 181, 228, 172, 257, 257, 257, 257, 184, 158, 158, 158, 158, 425, 425, 257, 257, 158, 158, 158, 158, 633, 172, 404, 184, 238, 405, 632, 257, 257, 257, 257, 257, 257, 158, 158, 158, 158, 158, 158, 158, 158, 289, 158, 158, 158, 158, 158, 158, 158, 158, 628, 298, 288, 436, 299, 443, 300, 301, 444, 668, 627, 290, 302, 302, 302, 302, 298, 437, 668, 626, 292, 303, 303, 303, 461, 461, 291, 299, 293, 346, 346, 346, 184, 300, 625, 300, 301, 388, 388, 388, 668, 184, 668, 305, 305, 304, 304, 304, 304, 158, 158, 158, 158, 496, 496, 181, 304, 304, 307, 307, 307, 307, 181, 184, 624, 308, 308, 308, 623, 304, 304, 304, 304, 304, 304, 619, 181, 337, 184, 310, 310, 158, 158, 158, 158, 184, 309, 309, 309, 309, 158, 158, 158, 158, 388, 388, 388, 309, 309, 184, 158, 158, 158, 158, 158, 158, 158, 158, 525, 525, 309, 309, 309, 309, 309, 309, 181, 336, 158, 158, 158, 158, 345, 345, 345, 345, 668, 512, 618, 349, 349, 349, 349, 668, 617, 513, 352, 352, 338, 184, 668, 339, 340, 350, 350, 350, 479, 181, 480, 184, 353, 353, 353, 353, 181, 616, 184, 308, 308, 308, 550, 550, 615, 184, 351, 351, 351, 351, 356, 614, 184, 357, 567, 567, 358, 351, 351, 184, 181, 668, 181, 355, 355, 158, 158, 158, 158, 610, 351, 351, 351, 351, 351, 351, 354, 354, 354, 354, 580, 580, 609, 184, 184, 184, 608, 354, 354, 158, 158, 158, 158, 380, 158, 158, 158, 158, 668, 607, 354, 354, 354, 354, 354, 354, 158, 158, 158, 158, 606, 158, 158, 158, 158, 387, 387, 387, 387, 668, 605, 184, 391, 391, 391, 391, 591, 591, 668, 601, 381, 350, 350, 350, 668, 382, 383, 393, 393, 602, 602, 600, 184, 181, 611, 611, 394, 394, 394, 394, 599, 184, 392, 392, 392, 392, 598, 184, 158, 158, 158, 158, 597, 392, 392, 181, 184, 596, 396, 396, 158, 158, 158, 158, 620, 620, 392, 392, 392, 392, 392, 392, 395, 395, 395, 395, 629, 629, 184, 158, 158, 158, 158, 395, 395, 419, 158, 158, 158, 158, 423, 423, 423, 423, 636, 636, 395, 395, 395, 395, 395, 395, 668, 420, 595, 426, 426, 426, 426, 668, 181, 181, 428, 428, 429, 429, 429, 429, 668, 181, 594, 421, 431, 431, 590, 184, 427, 427, 427, 427, 642, 642, 184, 184, 184, 647, 647, 427, 427, 652, 652, 184, 184, 158, 158, 158, 158, 657, 657, 589, 427, 427, 427, 427, 427, 427, 430, 430, 430, 430, 158, 158, 158, 158, 662, 662, 588, 430, 430, 158, 158, 158, 158, 459, 459, 459, 459, 666, 666, 587, 430, 430, 430, 430, 430, 430, 455, 668, 197, 197, 462, 462, 462, 462, 586, 668, 585, 457, 464, 464, 347, 456, 181, 347, 584, 465, 465, 465, 465, 583, 184, 463, 463, 463, 463, 579, 389, 424, 184, 389, 424, 578, 463, 463, 181, 184, 577, 467, 467, 158, 158, 158, 158, 576, 575, 463, 463, 463, 463, 463, 463, 466, 466, 466, 466, 574, 573, 184, 158, 158, 158, 158, 466, 466, 158, 158, 158, 158, 494, 494, 494, 494, 572, 571, 570, 466, 466, 466, 466, 466, 466, 668, 566, 565, 497, 497, 497, 497, 668, 564, 181, 499, 499, 500, 500, 500, 500, 181, 563, 460, 501, 501, 460, 562, 184, 492, 498, 498, 498, 498, 561, 184, 495, 184, 560, 495, 246, 498, 498, 246, 184, 158, 158, 158, 158, 524, 524, 524, 524, 559, 498, 498, 498, 498, 498, 498, 668, 558, 557, 526, 526, 526, 526, 668, 556, 181, 527, 527, 528, 528, 549, 549, 549, 549, 668, 555, 554, 551, 551, 184, 181, 553, 548, 552, 552, 547, 184, 668, 184, 181, 568, 568, 569, 569, 546, 668, 545, 184, 581, 581, 544, 181, 543, 184, 582, 582, 542, 541, 540, 539, 184, 668, 184, 181, 592, 592, 593, 593, 184, 668, 538, 537, 603, 603, 184, 181, 536, 668, 604, 604, 612, 612, 535, 534, 184, 181, 184, 668, 613, 613, 621, 621, 184, 181, 533, 532, 622, 622, 184, 668, 184, 181, 630, 630, 631, 631, 531, 530, 184, 668, 184, 181, 637, 637, 638, 638, 184, 668, 529, 523, 643, 643, 184, 181, 184, 668, 644, 644, 648, 648, 522, 521, 184, 181, 184, 668, 649, 649, 653, 653, 184, 181, 520, 519, 654, 654, 184, 668, 184, 181, 658, 658, 659, 659, 518, 517, 184, 668, 184, 516, 663, 663, 515, 514, 184, 511, 510, 509, 508, 507, 184, 506, 184, 505, 504, 503, 502, 493, 491, 490, 184, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 113, 113, 489, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 133, 488, 487, 133, 133, 138, 138, 486, 138, 138, 138, 138, 138, 485, 138, 138, 138, 138, 138, 140, 140, 484, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 150, 150, 483, 150, 150, 482, 150, 150, 150, 150, 150, 150, 150, 150, 152, 152, 481, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 158, 478, 477, 158, 158, 160, 476, 473, 160, 160, 167, 167, 472, 167, 167, 167, 167, 167, 167, 471, 167, 167, 167, 167, 170, 170, 470, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 182, 182, 182, 469, 468, 182, 182, 458, 182, 182, 182, 182, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 198, 198, 454, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 216, 216, 453, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 226, 226, 452, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 229, 229, 451, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 236, 236, 450, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 245, 245, 449, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 246, 448, 447, 246, 246, 246, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 446, 445, 248, 248, 248, 259, 442, 441, 259, 259, 438, 259, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 435, 434, 433, 432, 422, 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 403, 402, 401, 400, 399, 398, 397, 386, 385, 384, 379, 378, 377, 376, 375, 374, 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 344, 343, 342, 341, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 321, 318, 317, 316, 315, 314, 313, 312, 311, 260, 253, 297, 296, 295, 294, 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, 271, 270, 269, 264, 263, 262, 261, 260, 668, 254, 247, 242, 241, 240, 239, 225, 220, 219, 218, 217, 132, 212, 211, 207, 206, 203, 202, 201, 191, 169, 168, 157, 156, 151, 147, 146, 145, 144, 139, 137, 136, 135, 132, 130, 112, 668, 15, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668 } ; static yyconst flex_int16_t yy_chk[1892] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 20, 5, 5, 11, 11, 6, 6, 147, 3, 439, 4, 17, 7, 7, 17, 29, 7, 439, 8, 8, 12, 12, 8, 147, 11, 148, 29, 31, 31, 31, 31, 148, 20, 49, 5, 5, 5, 665, 6, 6, 6, 12, 32, 32, 32, 32, 661, 7, 5, 7, 49, 51, 6, 8, 51, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 22, 660, 22, 38, 38, 38, 38, 38, 38, 38, 38, 59, 63, 67, 59, 38, 67, 73, 22, 22, 73, 97, 22, 656, 91, 91, 22, 91, 91, 22, 90, 22, 97, 22, 91, 22, 22, 22, 75, 75, 75, 75, 655, 113, 63, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 115, 90, 81, 81, 81, 81, 99, 99, 99, 99, 111, 651, 121, 111, 113, 127, 78, 121, 143, 127, 99, 143, 650, 140, 80, 77, 81, 270, 99, 127, 79, 141, 115, 124, 80, 100, 100, 100, 100, 105, 140, 270, 105, 99, 105, 105, 152, 124, 141, 100, 124, 154, 155, 159, 105, 155, 159, 100, 103, 103, 103, 103, 170, 646, 172, 105, 131, 131, 131, 131, 645, 105, 103, 105, 105, 177, 641, 210, 152, 177, 103, 210, 205, 154, 205, 640, 103, 103, 103, 103, 103, 103, 103, 103, 170, 103, 172, 635, 103, 134, 134, 134, 134, 134, 134, 134, 134, 160, 160, 160, 160, 134, 161, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, 166, 166, 180, 180, 180, 180, 192, 633, 161, 182, 182, 182, 182, 163, 404, 198, 404, 248, 162, 188, 188, 188, 188, 182, 180, 199, 164, 184, 165, 192, 184, 182, 184, 184, 185, 185, 185, 185, 206, 166, 248, 188, 184, 254, 254, 632, 182, 198, 185, 187, 187, 187, 187, 184, 200, 206, 185, 199, 226, 184, 227, 184, 184, 187, 193, 228, 236, 193, 193, 193, 193, 187, 194, 301, 301, 194, 194, 194, 306, 306, 196, 329, 628, 196, 196, 237, 200, 193, 238, 627, 226, 329, 227, 348, 348, 194, 195, 228, 236, 195, 195, 195, 195, 196, 230, 230, 230, 230, 390, 390, 195, 195, 231, 231, 231, 231, 626, 237, 363, 195, 238, 363, 624, 195, 195, 195, 195, 195, 195, 232, 232, 232, 232, 233, 233, 233, 233, 231, 234, 234, 234, 234, 235, 235, 235, 235, 619, 247, 230, 401, 247, 407, 247, 247, 407, 249, 618, 232, 249, 249, 249, 249, 247, 401, 250, 617, 234, 250, 250, 250, 425, 425, 233, 247, 235, 299, 299, 299, 249, 247, 616, 247, 247, 346, 346, 346, 252, 250, 251, 252, 252, 251, 251, 251, 251, 289, 289, 289, 289, 461, 461, 255, 251, 251, 255, 255, 255, 255, 256, 252, 615, 256, 256, 256, 614, 251, 251, 251, 251, 251, 251, 610, 258, 289, 255, 258, 258, 288, 288, 288, 288, 256, 257, 257, 257, 257, 290, 290, 290, 290, 388, 388, 388, 257, 257, 258, 291, 291, 291, 291, 292, 292, 292, 292, 496, 496, 257, 257, 257, 257, 257, 257, 466, 288, 293, 293, 293, 293, 298, 298, 298, 298, 302, 479, 609, 302, 302, 302, 302, 305, 608, 479, 305, 305, 291, 466, 303, 292, 293, 303, 303, 303, 443, 307, 443, 302, 307, 307, 307, 307, 308, 607, 305, 308, 308, 308, 525, 525, 606, 303, 304, 304, 304, 304, 311, 605, 307, 311, 550, 550, 311, 304, 304, 308, 310, 498, 500, 310, 310, 336, 336, 336, 336, 600, 304, 304, 304, 304, 304, 304, 309, 309, 309, 309, 567, 567, 599, 310, 498, 500, 598, 309, 309, 337, 337, 337, 337, 336, 338, 338, 338, 338, 526, 597, 309, 309, 309, 309, 309, 309, 339, 339, 339, 339, 595, 340, 340, 340, 340, 345, 345, 345, 345, 349, 594, 526, 349, 349, 349, 349, 580, 580, 350, 590, 337, 350, 350, 350, 352, 338, 340, 352, 352, 591, 591, 589, 349, 353, 602, 602, 353, 353, 353, 353, 588, 350, 351, 351, 351, 351, 587, 352, 380, 380, 380, 380, 586, 351, 351, 355, 353, 585, 355, 355, 381, 381, 381, 381, 611, 611, 351, 351, 351, 351, 351, 351, 354, 354, 354, 354, 620, 620, 355, 382, 382, 382, 382, 354, 354, 380, 383, 383, 383, 383, 387, 387, 387, 387, 629, 629, 354, 354, 354, 354, 354, 354, 391, 382, 584, 391, 391, 391, 391, 393, 659, 394, 393, 393, 394, 394, 394, 394, 663, 396, 583, 383, 396, 396, 578, 391, 392, 392, 392, 392, 636, 636, 393, 659, 394, 642, 642, 392, 392, 647, 647, 663, 396, 419, 419, 419, 419, 652, 652, 577, 392, 392, 392, 392, 392, 392, 395, 395, 395, 395, 420, 420, 420, 420, 657, 657, 576, 395, 395, 421, 421, 421, 421, 423, 423, 423, 423, 662, 662, 575, 395, 395, 395, 395, 395, 395, 419, 426, 685, 685, 426, 426, 426, 426, 574, 428, 572, 421, 428, 428, 698, 420, 429, 698, 571, 429, 429, 429, 429, 570, 426, 427, 427, 427, 427, 565, 699, 700, 428, 699, 700, 563, 427, 427, 431, 429, 561, 431, 431, 455, 455, 455, 455, 560, 558, 427, 427, 427, 427, 427, 427, 430, 430, 430, 430, 557, 556, 431, 456, 456, 456, 456, 430, 430, 457, 457, 457, 457, 459, 459, 459, 459, 555, 554, 553, 430, 430, 430, 430, 430, 430, 462, 546, 544, 462, 462, 462, 462, 464, 543, 465, 464, 464, 465, 465, 465, 465, 467, 542, 701, 467, 467, 701, 541, 462, 456, 463, 463, 463, 463, 540, 464, 702, 465, 539, 702, 703, 463, 463, 703, 467, 492, 492, 492, 492, 494, 494, 494, 494, 538, 463, 463, 463, 463, 463, 463, 497, 536, 535, 497, 497, 497, 497, 499, 533, 501, 499, 499, 501, 501, 524, 524, 524, 524, 527, 532, 531, 527, 527, 497, 528, 529, 522, 528, 528, 521, 499, 551, 501, 552, 551, 551, 552, 552, 520, 568, 519, 527, 568, 568, 518, 569, 517, 528, 569, 569, 516, 515, 514, 513, 551, 581, 552, 582, 581, 581, 582, 582, 568, 592, 512, 510, 592, 592, 569, 593, 509, 603, 593, 593, 603, 603, 508, 507, 581, 604, 582, 612, 604, 604, 612, 612, 592, 613, 506, 505, 613, 613, 593, 621, 603, 622, 621, 621, 622, 622, 504, 503, 604, 630, 612, 631, 630, 630, 631, 631, 613, 637, 502, 490, 637, 637, 621, 638, 622, 643, 638, 638, 643, 643, 489, 488, 630, 644, 631, 648, 644, 644, 648, 648, 637, 649, 487, 486, 649, 649, 638, 653, 643, 654, 653, 653, 654, 654, 485, 484, 644, 658, 648, 483, 658, 658, 481, 480, 649, 478, 477, 476, 475, 474, 653, 473, 654, 472, 471, 470, 469, 458, 454, 453, 658, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, 673, 673, 452, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 674, 451, 450, 674, 674, 675, 675, 449, 675, 675, 675, 675, 675, 448, 675, 675, 675, 675, 675, 676, 676, 447, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 677, 677, 446, 677, 677, 445, 677, 677, 677, 677, 677, 677, 677, 677, 678, 678, 444, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 679, 442, 441, 679, 679, 680, 440, 437, 680, 680, 681, 681, 436, 681, 681, 681, 681, 681, 681, 435, 681, 681, 681, 681, 682, 682, 434, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 683, 683, 433, 432, 683, 683, 422, 683, 683, 683, 683, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 686, 686, 418, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 687, 687, 416, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 688, 688, 415, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, 689, 689, 414, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 690, 690, 413, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 691, 691, 412, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 692, 411, 410, 692, 692, 692, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 694, 694, 409, 408, 694, 694, 694, 695, 406, 405, 695, 695, 403, 695, 696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 697, 400, 399, 398, 397, 384, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 367, 366, 364, 362, 361, 360, 359, 358, 357, 356, 344, 342, 341, 335, 334, 333, 332, 331, 330, 327, 325, 324, 323, 322, 320, 319, 318, 317, 315, 314, 313, 312, 297, 296, 295, 294, 287, 286, 285, 284, 283, 282, 280, 279, 278, 277, 276, 275, 274, 273, 271, 269, 268, 267, 266, 265, 264, 263, 261, 259, 253, 244, 242, 241, 240, 225, 224, 223, 222, 221, 220, 219, 218, 217, 215, 214, 213, 212, 211, 209, 208, 207, 204, 203, 202, 201, 197, 190, 186, 181, 176, 175, 174, 173, 149, 146, 145, 137, 136, 132, 126, 125, 123, 122, 120, 119, 118, 104, 89, 84, 71, 69, 62, 58, 57, 56, 53, 48, 42, 41, 39, 34, 30, 19, 15, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668 } ; extern int yy_flex_debug; int yy_flex_debug = 0; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; static char *yy_full_match; static int yy_lp; static int yy_looking_for_trail_begin = 0; static int yy_full_lp; static int *yy_full_state; #define YY_TRAILING_MASK 0x2000 #define YY_TRAILING_HEAD_MASK 0x4000 #define REJECT \ { \ *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ (yy_lp) = (yy_full_lp); /* restore orig. accepting pos. */ \ (yy_state_ptr) = (yy_full_state); /* restore orig. state */ \ yy_current_state = *(yy_state_ptr); /* restore curr. state */ \ ++(yy_lp); \ goto find_rule; \ } static int yy_more_flag = 0; static int yy_more_len = 0; #define yymore() ((yy_more_flag) = 1) #define YY_MORE_ADJ (yy_more_len) #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "kdev-pg-lexer.ll" #line 2 "kdev-pg-lexer.ll" /* This file is part of kdev-pg-qt Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include #include "kdev-pg.h" #include "kdev-pg-parser.hh" -#include -#include -#include +#include +#include +#include int inp(); void appendLineBuffer(); void newline(); void countNewlines(const char*, int); void yyerror(const char* ); extern int yyLine; extern int currentOffset; extern bool yymoreFlag; namespace KDevPG { extern QFile file; extern QFileInfo fileInfo; extern QTextStream checkOut; } #define YYMORE yymoreFlag = true; yymore(); #define YY_INPUT(buf, result, max_size) \ { \ int c = inp(); \ result = (c == EOF) ? YY_NULL : (buf[0] = (char)c, 1); \ } #define YY_USER_ACTION appendLineBuffer(); #define COPY_TO_YYLVAL(string, len) \ yylval.str = (char*) calloc(len+1, sizeof(char)); \ strncpy(yylval.str, string, len); \ yylval.str[len] = '\0'; #define COPY_CODE_TO_YYLVAL(string, len) \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::BeautifulCode) \ { \ COPY_TO_YYLVAL(string, len) \ } \ else \ { \ QByteArray tmp("\n#"); \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::CompatibilityLineNumbers) \ tmp += "line"; \ tmp += " " + QString::number(firstCodeLine).toLocal8Bit(); \ tmp += " \"" + KDevPG::fileInfo.absoluteFilePath().toLocal8Bit() + "\""; \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::FullLineNumbers) \ tmp += " 1"; \ tmp += "\n"; \ size_t memlen = tmp.size() + firstCodeColumn + len + 16 + 1; \ yylval.str = (char*) calloc(memlen, sizeof(char)); \ strncpy(yylval.str, tmp.data(), tmp.size()); \ memset(yylval.str + tmp.size(), ' ', firstCodeColumn); \ strncpy(yylval.str + tmp.size() + firstCodeColumn, string, len); \ yylval.str[memlen-1] = '\0'; \ } #define ESCAPE_CHARACTER(chr) \ yylval.str = (char*) calloc(2, sizeof(char)); yylval.str[0] = chr; yylval.str[1] = '\0'; return T_STRING; namespace { enum RulePosition { RuleBody, RuleFooter, RuleLexer }; RulePosition rulePosition = RuleBody; int openBrackets; // for rule arguments and regexp usage int firstCodeLine; // where the current code-block begins int firstCodeColumn; } #ifdef _WIN32 #include #else #include #endif #line 1284 "kdev-pg-lexer.cc" #define INITIAL 0 #define CODE 1 #define PARSERCLASS 2 #define RULE_ARGUMENTS 3 #define RULE_PARAMETERS_HEADER 4 #define RULE_PARAMETERS_VARNAME 5 #define RULE_LEXER 6 #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * _in_str ); FILE *yyget_out (void ); void yyset_out (FILE * _out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput (int c,char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif /* Create the reject buffer large enough to save one state per allowed character. */ if ( ! (yy_state_buf) ) (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ); if ( ! (yy_state_buf) ) YY_FATAL_ERROR( "out of dynamic memory in yylex()" ); if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 118 "kdev-pg-lexer.ll" #line 1510 "kdev-pg-lexer.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { (yy_more_len) = 0; if ( (yy_more_flag) ) { (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); (yy_more_flag) = 0; } yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; *(yy_state_ptr)++ = yy_current_state; ++yy_cp; } while ( yy_base[yy_current_state] != 1821 ); yy_find_action: yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; find_rule: /* we branch to this label when backing up */ for ( ; ; ) /* until we find what rule we matched */ { if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) { yy_act = yy_acclist[(yy_lp)]; if ( yy_act & YY_TRAILING_HEAD_MASK || (yy_looking_for_trail_begin) ) { if ( yy_act == (yy_looking_for_trail_begin) ) { (yy_looking_for_trail_begin) = 0; yy_act &= ~YY_TRAILING_HEAD_MASK; break; } } else if ( yy_act & YY_TRAILING_MASK ) { (yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK; (yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK; (yy_full_match) = yy_cp; (yy_full_state) = (yy_state_ptr); (yy_full_lp) = (yy_lp); } else { (yy_full_match) = yy_cp; (yy_full_state) = (yy_state_ptr); (yy_full_lp) = (yy_lp); break; } ++(yy_lp); goto find_rule; } --yy_cp; yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 1: YY_RULE_SETUP #line 121 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 122 "kdev-pg-lexer.ll" newline(); YY_BREAK case 3: YY_RULE_SETUP #line 123 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 4: YY_RULE_SETUP #line 125 "kdev-pg-lexer.ll" rulePosition = RuleBody; return ';'; YY_BREAK case 5: YY_RULE_SETUP #line 126 "kdev-pg-lexer.ll" if(rulePosition == RuleLexer) BEGIN(RULE_LEXER); else rulePosition = RuleFooter; return T_ARROW; YY_BREAK case 6: YY_RULE_SETUP #line 127 "kdev-pg-lexer.ll" return T_INLINE; YY_BREAK case 7: YY_RULE_SETUP #line 129 "kdev-pg-lexer.ll" return '('; YY_BREAK case 8: YY_RULE_SETUP #line 130 "kdev-pg-lexer.ll" return ')'; YY_BREAK case 9: YY_RULE_SETUP #line 131 "kdev-pg-lexer.ll" return '{'; YY_BREAK case 10: YY_RULE_SETUP #line 132 "kdev-pg-lexer.ll" return '}'; YY_BREAK case 11: YY_RULE_SETUP #line 133 "kdev-pg-lexer.ll" return ','; YY_BREAK case 12: YY_RULE_SETUP #line 134 "kdev-pg-lexer.ll" return '0'; YY_BREAK case 13: YY_RULE_SETUP #line 135 "kdev-pg-lexer.ll" return '#'; YY_BREAK case 14: YY_RULE_SETUP #line 136 "kdev-pg-lexer.ll" return '.'; YY_BREAK case 15: YY_RULE_SETUP #line 137 "kdev-pg-lexer.ll" return ':'; YY_BREAK case 16: YY_RULE_SETUP #line 138 "kdev-pg-lexer.ll" return '='; YY_BREAK case 17: YY_RULE_SETUP #line 139 "kdev-pg-lexer.ll" return '+'; YY_BREAK case 18: YY_RULE_SETUP #line 140 "kdev-pg-lexer.ll" return '*'; YY_BREAK case 19: YY_RULE_SETUP #line 141 "kdev-pg-lexer.ll" return '?'; YY_BREAK case 20: YY_RULE_SETUP #line 142 "kdev-pg-lexer.ll" return '@'; YY_BREAK case 21: YY_RULE_SETUP #line 143 "kdev-pg-lexer.ll" return '|'; YY_BREAK case 22: YY_RULE_SETUP #line 144 "kdev-pg-lexer.ll" return '&'; YY_BREAK case 23: YY_RULE_SETUP #line 146 "kdev-pg-lexer.ll" return T_TRY_RECOVER; YY_BREAK case 24: YY_RULE_SETUP #line 147 "kdev-pg-lexer.ll" return T_TRY_ROLLBACK; YY_BREAK case 25: YY_RULE_SETUP #line 148 "kdev-pg-lexer.ll" return T_CATCH; YY_BREAK case 26: YY_RULE_SETUP #line 150 "kdev-pg-lexer.ll" return T_EXPORT_MACRO; YY_BREAK case 27: YY_RULE_SETUP #line 151 "kdev-pg-lexer.ll" return T_EXPORT_MACRO_HEADER; YY_BREAK case 28: YY_RULE_SETUP #line 152 "kdev-pg-lexer.ll" return T_TOKEN_DECLARATION; YY_BREAK case 29: YY_RULE_SETUP #line 153 "kdev-pg-lexer.ll" return T_TOKEN_STREAM_DECLARATION; YY_BREAK case 30: YY_RULE_SETUP #line 154 "kdev-pg-lexer.ll" return T_NAMESPACE_DECLARATION; YY_BREAK case 31: YY_RULE_SETUP #line 155 "kdev-pg-lexer.ll" BEGIN(PARSERCLASS); return T_PARSERCLASS_DECLARATION; YY_BREAK case 32: YY_RULE_SETUP #line 156 "kdev-pg-lexer.ll" BEGIN(PARSERCLASS); return T_LEXERCLASS_DECLARATION; YY_BREAK case 33: YY_RULE_SETUP #line 157 "kdev-pg-lexer.ll" return T_INPUT_STREAM; YY_BREAK case 34: YY_RULE_SETUP #line 158 "kdev-pg-lexer.ll" return T_AST_DECLARATION; YY_BREAK case 35: YY_RULE_SETUP #line 159 "kdev-pg-lexer.ll" return T_PARSER_DECLARATION_HEADER; YY_BREAK case 36: YY_RULE_SETUP #line 160 "kdev-pg-lexer.ll" return T_PARSER_BITS_HEADER; YY_BREAK case 37: YY_RULE_SETUP #line 161 "kdev-pg-lexer.ll" return T_AST_HEADER; YY_BREAK case 38: YY_RULE_SETUP #line 162 "kdev-pg-lexer.ll" return T_LEXER_DECLARATION_HEADER; YY_BREAK case 39: YY_RULE_SETUP #line 163 "kdev-pg-lexer.ll" return T_LEXER_BITS_HEADER; YY_BREAK case 40: YY_RULE_SETUP #line 164 "kdev-pg-lexer.ll" return T_INPUT_ENCODING; YY_BREAK case 41: YY_RULE_SETUP #line 165 "kdev-pg-lexer.ll" return T_TABLE_LEXER; YY_BREAK case 42: YY_RULE_SETUP #line 166 "kdev-pg-lexer.ll" return T_SEQUENCE_LEXER; YY_BREAK case 43: YY_RULE_SETUP #line 167 "kdev-pg-lexer.ll" return T_AST_BASE; YY_BREAK case 44: YY_RULE_SETUP #line 168 "kdev-pg-lexer.ll" return T_PARSER_BASE; YY_BREAK case 45: YY_RULE_SETUP #line 169 "kdev-pg-lexer.ll" return T_LEXER_BASE; YY_BREAK case 46: YY_RULE_SETUP #line 170 "kdev-pg-lexer.ll" return T_BIN; YY_BREAK case 47: YY_RULE_SETUP #line 171 "kdev-pg-lexer.ll" return T_PRE; YY_BREAK case 48: YY_RULE_SETUP #line 172 "kdev-pg-lexer.ll" return T_POST; YY_BREAK case 49: YY_RULE_SETUP #line 173 "kdev-pg-lexer.ll" return T_TERN; YY_BREAK case 50: YY_RULE_SETUP #line 174 "kdev-pg-lexer.ll" return T_PAREN; YY_BREAK case 51: YY_RULE_SETUP #line 175 "kdev-pg-lexer.ll" return T_PRIORITY; YY_BREAK case 52: YY_RULE_SETUP #line 176 "kdev-pg-lexer.ll" rulePosition = RuleBody; return T_LOPR; YY_BREAK case 53: YY_RULE_SETUP #line 177 "kdev-pg-lexer.ll" rulePosition = RuleFooter; return T_ROPR; YY_BREAK case 54: YY_RULE_SETUP #line 178 "kdev-pg-lexer.ll" return T_LEFT_ASSOC; YY_BREAK case 55: YY_RULE_SETUP #line 179 "kdev-pg-lexer.ll" return T_RIGHT_ASSOC; YY_BREAK case 56: YY_RULE_SETUP #line 180 "kdev-pg-lexer.ll" return T_IS_LEFT_ASSOC; YY_BREAK case 57: YY_RULE_SETUP #line 181 "kdev-pg-lexer.ll" return T_IS_RIGHT_ASSOC; YY_BREAK case 58: YY_RULE_SETUP #line 182 "kdev-pg-lexer.ll" rulePosition = RuleLexer; return T_LEXER; YY_BREAK case 59: YY_RULE_SETUP #line 185 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 60: /* rule 60 can match eol */ YY_RULE_SETUP #line 186 "kdev-pg-lexer.ll" newline(); YY_BREAK case 61: YY_RULE_SETUP #line 187 "kdev-pg-lexer.ll" return '('; YY_BREAK case 62: YY_RULE_SETUP #line 188 "kdev-pg-lexer.ll" return T_PUBLIC; YY_BREAK case 63: YY_RULE_SETUP #line 189 "kdev-pg-lexer.ll" return T_PRIVATE; YY_BREAK case 64: YY_RULE_SETUP #line 190 "kdev-pg-lexer.ll" return T_PROTECTED; YY_BREAK case 65: YY_RULE_SETUP #line 191 "kdev-pg-lexer.ll" return T_DECLARATION; YY_BREAK case 66: YY_RULE_SETUP #line 192 "kdev-pg-lexer.ll" return T_CONSTRUCTOR; YY_BREAK case 67: YY_RULE_SETUP #line 193 "kdev-pg-lexer.ll" return T_DESTRUCTOR; YY_BREAK case 68: YY_RULE_SETUP #line 194 "kdev-pg-lexer.ll" return T_BITS; YY_BREAK case 69: YY_RULE_SETUP #line 195 "kdev-pg-lexer.ll" BEGIN(INITIAL); return ')'; YY_BREAK case 70: YY_RULE_SETUP #line 196 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 71: YY_RULE_SETUP #line 200 "kdev-pg-lexer.ll" { if (rulePosition == RuleBody) { /* use the arguments in a rule call */ firstCodeLine = yyLine; openBrackets = 0; BEGIN(RULE_ARGUMENTS); } else if (rulePosition == RuleFooter) { /* declare the arguments */ BEGIN(RULE_PARAMETERS_HEADER); return '['; } } YY_BREAK case 72: YY_RULE_SETUP #line 212 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 73: /* rule 73 can match eol */ YY_RULE_SETUP #line 213 "kdev-pg-lexer.ll" newline(); YY_BREAK case 74: YY_RULE_SETUP #line 214 "kdev-pg-lexer.ll" ++yytext; COPY_TO_YYLVAL(yytext,yyleng-2); return T_NAMED_REGEXP; YY_BREAK case 75: /* rule 75 can match eol */ YY_RULE_SETUP #line 215 "kdev-pg-lexer.ll" countNewlines(yytext, yyleng); rulePosition = RuleBody; BEGIN(INITIAL); return ';'; YY_BREAK case 76: YY_RULE_SETUP #line 216 "kdev-pg-lexer.ll" return ';'; YY_BREAK case 77: YY_RULE_SETUP #line 217 "kdev-pg-lexer.ll" ++openBrackets; return '['; YY_BREAK case 78: YY_RULE_SETUP #line 218 "kdev-pg-lexer.ll" --openBrackets; return ']'; YY_BREAK case 79: YY_RULE_SETUP #line 219 "kdev-pg-lexer.ll" ++openBrackets; return '('; YY_BREAK case 80: YY_RULE_SETUP #line 220 "kdev-pg-lexer.ll" --openBrackets; return ')'; YY_BREAK case 81: YY_RULE_SETUP #line 221 "kdev-pg-lexer.ll" return '?'; YY_BREAK case 82: YY_RULE_SETUP #line 222 "kdev-pg-lexer.ll" return '|'; YY_BREAK case 83: YY_RULE_SETUP #line 223 "kdev-pg-lexer.ll" return '^'; YY_BREAK case 84: YY_RULE_SETUP #line 224 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_RANGE; YY_BREAK case 85: YY_RULE_SETUP #line 225 "kdev-pg-lexer.ll" return '&'; YY_BREAK case 86: YY_RULE_SETUP #line 226 "kdev-pg-lexer.ll" return '~'; YY_BREAK case 87: YY_RULE_SETUP #line 227 "kdev-pg-lexer.ll" return '*'; YY_BREAK case 88: YY_RULE_SETUP #line 228 "kdev-pg-lexer.ll" return '+'; YY_BREAK case 89: YY_RULE_SETUP #line 229 "kdev-pg-lexer.ll" return '@'; YY_BREAK case 90: YY_RULE_SETUP #line 230 "kdev-pg-lexer.ll" return '.'; YY_BREAK case 91: YY_RULE_SETUP #line 231 "kdev-pg-lexer.ll" return T_ARROW; YY_BREAK case 92: YY_RULE_SETUP #line 232 "kdev-pg-lexer.ll" return T_CONTINUE; YY_BREAK case 93: YY_RULE_SETUP #line 233 "kdev-pg-lexer.ll" return T_FAIL; YY_BREAK case 94: YY_RULE_SETUP #line 234 "kdev-pg-lexer.ll" return T_ENTER_RULE_SET; YY_BREAK case 95: YY_RULE_SETUP #line 235 "kdev-pg-lexer.ll" return T_LEAVE_RULE_SET; YY_BREAK case 96: YY_RULE_SETUP #line 236 "kdev-pg-lexer.ll" return T_LOOKAHEAD; YY_BREAK case 97: YY_RULE_SETUP #line 237 "kdev-pg-lexer.ll" return T_BARRIER; YY_BREAK case 98: YY_RULE_SETUP #line 238 "kdev-pg-lexer.ll" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); YY_BREAK case 99: /* rule 99 can match eol */ YY_RULE_SETUP #line 239 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; YY_BREAK case 100: /* rule 100 can match eol */ YY_RULE_SETUP #line 240 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 101: YY_RULE_SETUP #line 241 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_UNQUOTED_STRING; YY_BREAK case 102: YY_RULE_SETUP #line 242 "kdev-pg-lexer.ll" /* skip */ YY_BREAK case 103: YY_RULE_SETUP #line 243 "kdev-pg-lexer.ll" yytext++; COPY_TO_YYLVAL(yytext,yyleng-2); return T_STRING; YY_BREAK case YY_STATE_EOF(RULE_LEXER): #line 245 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule lexer definition..." << endl; yyerror(""); return 0; } YY_BREAK case 104: /* rule 104 can match eol */ YY_RULE_SETUP #line 254 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 105: YY_RULE_SETUP #line 255 "kdev-pg-lexer.ll" YYMORE; /* this and... */ YY_BREAK case 106: YY_RULE_SETUP #line 256 "kdev-pg-lexer.ll" YYMORE; /* ...this prevent brackets inside strings to be counted */ YY_BREAK case 107: YY_RULE_SETUP #line 257 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a bracket, and append what comes next */ YY_BREAK case 108: YY_RULE_SETUP #line 258 "kdev-pg-lexer.ll" openBrackets++; YYMORE; YY_BREAK case 109: YY_RULE_SETUP #line 259 "kdev-pg-lexer.ll" { openBrackets--; if (openBrackets < 0) { COPY_CODE_TO_YYLVAL(yytext,(yyleng-1)); /* cut off the trailing bracket */ BEGIN(INITIAL); return T_RULE_ARGUMENTS; } } YY_BREAK case YY_STATE_EOF(RULE_ARGUMENTS): #line 267 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule argument specification..." << endl; yyerror(""); return 0; } YY_BREAK case 110: YY_RULE_SETUP #line 276 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 111: /* rule 111 can match eol */ YY_RULE_SETUP #line 277 "kdev-pg-lexer.ll" newline(); YY_BREAK case 112: YY_RULE_SETUP #line 278 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 113: YY_RULE_SETUP #line 279 "kdev-pg-lexer.ll" BEGIN(RULE_PARAMETERS_VARNAME); return ':'; YY_BREAK case 114: YY_RULE_SETUP #line 280 "kdev-pg-lexer.ll" return '#'; YY_BREAK case 115: YY_RULE_SETUP #line 281 "kdev-pg-lexer.ll" return T_MEMBER; YY_BREAK case 116: YY_RULE_SETUP #line 282 "kdev-pg-lexer.ll" return T_TEMPORARY; YY_BREAK case 117: YY_RULE_SETUP #line 283 "kdev-pg-lexer.ll" return T_ARGUMENT; YY_BREAK case 118: YY_RULE_SETUP #line 284 "kdev-pg-lexer.ll" return T_NODE; YY_BREAK case 119: YY_RULE_SETUP #line 285 "kdev-pg-lexer.ll" return T_TOKEN; YY_BREAK case 120: YY_RULE_SETUP #line 286 "kdev-pg-lexer.ll" return T_VARIABLE; YY_BREAK case 121: YY_RULE_SETUP #line 287 "kdev-pg-lexer.ll" return ';'; /* only used for "token" types */ YY_BREAK case 122: YY_RULE_SETUP #line 288 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 123: YY_RULE_SETUP #line 289 "kdev-pg-lexer.ll" BEGIN(INITIAL); return ']'; YY_BREAK case 124: YY_RULE_SETUP #line 290 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 125: /* rule 125 can match eol */ YY_RULE_SETUP #line 294 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 126: YY_RULE_SETUP #line 295 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a semicolon, and append what comes next */ YY_BREAK case 127: YY_RULE_SETUP #line 296 "kdev-pg-lexer.ll" { // strip trailing whitespace int length = yyleng-1; // and first, the trailing semicolon for (int i = length-1; i < 1; i--) { switch(yytext[i-1]) { case ' ': case '\f': case '\t': continue; default: length = i; break; } } COPY_TO_YYLVAL(yytext,length); BEGIN(RULE_PARAMETERS_HEADER); return T_IDENTIFIER; } YY_BREAK case 128: YY_RULE_SETUP #line 315 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 129: YY_RULE_SETUP #line 319 "kdev-pg-lexer.ll" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP #line 321 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 131: YY_RULE_SETUP #line 322 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a colon, and append what comes next */ YY_BREAK case 132: YY_RULE_SETUP #line 323 "kdev-pg-lexer.ll" YYMORE; /* also gather colons that are not followed by colons or newlines */ YY_BREAK case 133: YY_RULE_SETUP #line 324 "kdev-pg-lexer.ll" { COPY_CODE_TO_YYLVAL(yytext, (yyleng-2)); /* cut off the trailing stuff */ if(rulePosition == RuleLexer) BEGIN(RULE_LEXER); else BEGIN(INITIAL); return T_CODE; } YY_BREAK case YY_STATE_EOF(CODE): #line 332 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed code segment..." << endl; yyerror(""); return 0; } YY_BREAK case 134: YY_RULE_SETUP #line 341 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; YY_BREAK case 135: YY_RULE_SETUP #line 342 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 136: YY_RULE_SETUP #line 343 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_NUMBER; YY_BREAK case 137: YY_RULE_SETUP #line 346 "kdev-pg-lexer.ll" { yytext++; /* start inside the quotes */ COPY_TO_YYLVAL(yytext,yyleng-2); /* cut off the trailing quote */ return T_STRING; } YY_BREAK case 138: YY_RULE_SETUP #line 352 "kdev-pg-lexer.ll" { KDevPG::checkOut << "Unexpected character: ``" << yytext[0] << "''" << endl; yyerror(""); } YY_BREAK case 139: YY_RULE_SETUP #line 358 "kdev-pg-lexer.ll" ECHO; YY_BREAK #line 2391 "kdev-pg-lexer.cc" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(PARSERCLASS): case YY_STATE_EOF(RULE_PARAMETERS_HEADER): case YY_STATE_EOF(RULE_PARAMETERS_VARNAME): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; *(yy_state_ptr)++ = yy_current_state; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; YY_CHAR yy_c = 1; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; yy_is_jam = (yy_current_state == 668); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,(int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; (yy_state_buf) = 0; (yy_state_ptr) = 0; (yy_full_match) = 0; (yy_lp) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; yyfree ( (yy_state_buf) ); (yy_state_buf) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 358 "kdev-pg-lexer.ll" char ch; int yyLine = 1, currentOffset = 0; bool endOfLine = false, yymoreFlag = false; int yyTextLineLeng = 1024; char *yyTextLine = (char*)malloc(yyTextLineLeng); int inp() { if( KDevPG::file.atEnd() ) return EOF; KDevPG::file.getChar( &ch ); return ch; } void newline() { ++yyLine; endOfLine = true; } void countNewlines(const char* code, int leng) { for(int i = 0; i != leng; ++i) if(code[i] == '\n') ++yyLine; } /* initialize the line buffer */ void clearLineBuffer() { yyTextLine[0] = '\0'; currentOffset = 0; endOfLine = false; } struct InitLineBuffer { InitLineBuffer() { clearLineBuffer(); } } _initLineBuffer; /* add the current token to the current line */ void appendLineBuffer() { if (endOfLine == true) clearLineBuffer(); static int lastTextLeng = 0; currentOffset = strlen(yyTextLine); /* start of current */ int newLeng = currentOffset + strlen(yytext) - (yymoreFlag ? lastTextLeng : 0) + 1; if(newLeng > yyTextLineLeng) { do { yyTextLineLeng *= 2; } while(newLeng > yyTextLineLeng); yyTextLine = (char*)realloc(yyTextLine, yyTextLineLeng); } strcpy(yyTextLine+currentOffset, yytext + (yymoreFlag ? lastTextLeng : 0)); /* append current */ /* strcpy is faster than strcat */ Q_ASSERT(strlen(yyTextLine) < size_t(yyTextLineLeng)); lastTextLeng = strlen(yytext); yymoreFlag = false; } void yyerror(const char* msg ) { Q_UNUSED(msg); KDevPG::checkOut << "** LEXICAL ERROR at line " << yyLine << " column " << currentOffset << endl; char *current_end = yyTextLine + strlen(yyTextLine); char *p; /* get the rest of the line if we are not already at the end */ if(!endOfLine) { p = current_end; int c = ch; while(c != EOF && c != '\n') { *p++ = c; c = inp(); } *p++ = '\n'; *p = 0; } /* yyTextLine[] now has the whole line, with the current token */ /* at currentOffset */ /* print error message and current line */ KDevPG::checkOut << yyTextLine; /* print a ^ under the most recent token */ KDevPG::checkOut << QString(currentOffset, ' ').append('^') << endl; /* currentOffset spaces, then ^ */ exit(EXIT_FAILURE); } int yywrap() { return 1; } diff --git a/kdev-pg/kdev-pg-lexer.ll b/kdev-pg/kdev-pg-lexer.ll index d8c1fa7..20ce99e 100644 --- a/kdev-pg/kdev-pg-lexer.ll +++ b/kdev-pg/kdev-pg-lexer.ll @@ -1,470 +1,470 @@ %{ /* This file is part of kdev-pg-qt Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include #include "kdev-pg.h" #include "kdev-pg-parser.hh" -#include -#include -#include +#include +#include +#include int inp(); void appendLineBuffer(); void newline(); void countNewlines(const char*, int); void yyerror(const char* ); extern int yyLine; extern int currentOffset; extern bool yymoreFlag; namespace KDevPG { extern QFile file; extern QFileInfo fileInfo; extern QTextStream checkOut; } #define YYMORE yymoreFlag = true; yymore(); #define YY_INPUT(buf, result, max_size) \ { \ int c = inp(); \ result = (c == EOF) ? YY_NULL : (buf[0] = (char)c, 1); \ } #define YY_USER_ACTION appendLineBuffer(); #define COPY_TO_YYLVAL(string, len) \ yylval.str = (char*) calloc(len+1, sizeof(char)); \ strncpy(yylval.str, string, len); \ yylval.str[len] = '\0'; #define COPY_CODE_TO_YYLVAL(string, len) \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::BeautifulCode) \ { \ COPY_TO_YYLVAL(string, len) \ } \ else \ { \ QByteArray tmp("\n#"); \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::CompatibilityLineNumbers) \ tmp += "line"; \ tmp += " " + QString::number(firstCodeLine).toLocal8Bit(); \ tmp += " \"" + KDevPG::fileInfo.absoluteFilePath().toLocal8Bit() + "\""; \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::FullLineNumbers) \ tmp += " 1"; \ tmp += "\n"; \ size_t memlen = tmp.size() + firstCodeColumn + len + 16 + 1; \ yylval.str = (char*) calloc(memlen, sizeof(char)); \ strncpy(yylval.str, tmp.data(), tmp.size()); \ memset(yylval.str + tmp.size(), ' ', firstCodeColumn); \ strncpy(yylval.str + tmp.size() + firstCodeColumn, string, len); \ yylval.str[memlen-1] = '\0'; \ } #define ESCAPE_CHARACTER(chr) \ yylval.str = (char*) calloc(2, sizeof(char)); yylval.str[0] = chr; yylval.str[1] = '\0'; return T_STRING; namespace { enum RulePosition { RuleBody, RuleFooter, RuleLexer }; RulePosition rulePosition = RuleBody; int openBrackets; // for rule arguments and regexp usage int firstCodeLine; // where the current code-block begins int firstCodeColumn; } #ifdef _WIN32 #include #else #include #endif %} Whitespace [ \f\t] Newline "\r\n"|\r|\n String ["]([^\r\n\"]|[\\][^\r\n])*["] Char [_a-zA-Z0-9]|\\[xXuU][0-9a-fA-F]{1,6}|\\[oO][0-7][0-7]*|\\[dD][0-9]{1,7}|\\[yY][01]{1,21}|\\[\x20-\x7f] %x CODE %x PARSERCLASS %x RULE_ARGUMENTS %x RULE_PARAMETERS_HEADER %x RULE_PARAMETERS_VARNAME %x RULE_LEXER %% {Whitespace}* /* skip */ ; {Newline} newline(); "--"[^\r\n]* /* line comments, skip */ ; ";"+ rulePosition = RuleBody; return ';'; "->" if(rulePosition == RuleLexer) BEGIN(RULE_LEXER); else rulePosition = RuleFooter; return T_ARROW; ".=" return T_INLINE; "(" return '('; ")" return ')'; "{" return '{'; "}" return '}'; "," return ','; "0" return '0'; "#" return '#'; "." return '.'; ":" return ':'; "=" return '='; "+" return '+'; "*" return '*'; "?" return '?'; "@" return '@'; "|" return '|'; "&" return '&'; "try/recover" return T_TRY_RECOVER; "try/rollback" return T_TRY_ROLLBACK; "catch" return T_CATCH; "%export_macro" return T_EXPORT_MACRO; "%export_macro_header" return T_EXPORT_MACRO_HEADER; "%token" return T_TOKEN_DECLARATION; "%token_stream" return T_TOKEN_STREAM_DECLARATION; "%namespace" return T_NAMESPACE_DECLARATION; "%parserclass" BEGIN(PARSERCLASS); return T_PARSERCLASS_DECLARATION; "%lexerclass" BEGIN(PARSERCLASS); return T_LEXERCLASS_DECLARATION; "%input_stream" return T_INPUT_STREAM; "%ast_extra_members" return T_AST_DECLARATION; "%parser_declaration_header" return T_PARSER_DECLARATION_HEADER; "%parser_bits_header" return T_PARSER_BITS_HEADER; "%ast_header" return T_AST_HEADER; "%lexer_declaration_header" return T_LEXER_DECLARATION_HEADER; "%lexer_bits_header" return T_LEXER_BITS_HEADER; "%input_encoding" return T_INPUT_ENCODING; "%table_lexer" return T_TABLE_LEXER; "%sequence_lexer" return T_SEQUENCE_LEXER; "%ast_base" return T_AST_BASE; "%parser_base" return T_PARSER_BASE; "%lexer_base" return T_LEXER_BASE; "%bin" return T_BIN; "%pre" return T_PRE; "%post" return T_POST; "%tern" return T_TERN; "%paren" return T_PAREN; "%priority" return T_PRIORITY; "%<" rulePosition = RuleBody; return T_LOPR; "%>" rulePosition = RuleFooter; return T_ROPR; "%left" return T_LEFT_ASSOC; "%right" return T_RIGHT_ASSOC; "%isLeft" return T_IS_LEFT_ASSOC; "%isRight" return T_IS_RIGHT_ASSOC; "%lexer" rulePosition = RuleLexer; return T_LEXER; { {Whitespace}* /* skip */ ; {Newline} newline(); "(" return '('; "public" return T_PUBLIC; "private" return T_PRIVATE; "protected" return T_PROTECTED; "declaration" return T_DECLARATION; "constructor" return T_CONSTRUCTOR; "destructor" return T_DESTRUCTOR; "bits" return T_BITS; ")" BEGIN(INITIAL); return ')'; . BEGIN(INITIAL); REJECT; /* everything else */ } "[" { if (rulePosition == RuleBody) { /* use the arguments in a rule call */ firstCodeLine = yyLine; openBrackets = 0; BEGIN(RULE_ARGUMENTS); } else if (rulePosition == RuleFooter) { /* declare the arguments */ BEGIN(RULE_PARAMETERS_HEADER); return '['; } } { "--"[^\r\n]* /* line comments, skip */ ; {Newline} newline(); "{"[a-zA-Z_][a-zA-Z_0-9]*"}" ++yytext; COPY_TO_YYLVAL(yytext,yyleng-2); return T_NAMED_REGEXP; ";"+(("--"[^\r\n]*[\r\n])|[ \f\t\r\n])+/";"+ countNewlines(yytext, yyleng); rulePosition = RuleBody; BEGIN(INITIAL); return ';'; ";"+ return ';'; "[" ++openBrackets; return '['; "]" --openBrackets; return ']'; "(" ++openBrackets; return '('; ")" --openBrackets; return ')'; "?" return '?'; "|" return '|'; "^" return '^'; {Char}"-"{Char} COPY_TO_YYLVAL(yytext,yyleng); return T_RANGE; "&" return '&'; "~" return '~'; "*" return '*'; "+" return '+'; "@" return '@'; "." return '.'; "->" return T_ARROW; "%continue" return T_CONTINUE; "%fail" return T_FAIL; "%enter" return T_ENTER_RULE_SET; "%leave" return T_LEAVE_RULE_SET; "%la" return T_LOOKAHEAD; "%ba" return T_BARRIER; "[:" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); [_A-Z]+/[ \f\t\r\n]*";" COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; [_a-zA-Z0-9]+/[ \f\t\r\n]*";" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; {Char}+ COPY_TO_YYLVAL(yytext,yyleng); return T_UNQUOTED_STRING; {Whitespace} /* skip */ {String} yytext++; COPY_TO_YYLVAL(yytext,yyleng-2); return T_STRING; <> { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule lexer definition..." << endl; yyerror(""); return 0; } } { {Newline} newline(); YYMORE; {String} YYMORE; /* this and... */ ["] YYMORE; /* ...this prevent brackets inside strings to be counted */ [^\[\]\n\r\"]* YYMORE; /* gather everything that's not a bracket, and append what comes next */ "[" openBrackets++; YYMORE; "]" { openBrackets--; if (openBrackets < 0) { COPY_CODE_TO_YYLVAL(yytext,(yyleng-1)); /* cut off the trailing bracket */ BEGIN(INITIAL); return T_RULE_ARGUMENTS; } } <> { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule argument specification..." << endl; yyerror(""); return 0; } } { {Whitespace}* /* skip */ ; {Newline} newline(); "--"[^\r\n]* /* line comments, skip */ ; ":"{Whitespace}* BEGIN(RULE_PARAMETERS_VARNAME); return ':'; "#" return '#'; "member" return T_MEMBER; "temporary" return T_TEMPORARY; "argument" return T_ARGUMENT; "node" return T_NODE; "token" return T_TOKEN; "variable" return T_VARIABLE; ";" return ';'; /* only used for "token" types */ [_a-zA-Z]*[_a-zA-Z0-9]+ COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; "]" BEGIN(INITIAL); return ']'; . BEGIN(INITIAL); REJECT; /* everything else */ } { {Newline} newline(); YYMORE; [^;\r\n]* YYMORE; /* gather everything that's not a semicolon, and append what comes next */ ";" { // strip trailing whitespace int length = yyleng-1; // and first, the trailing semicolon for (int i = length-1; i < 1; i--) { switch(yytext[i-1]) { case ' ': case '\f': case '\t': continue; default: length = i; break; } } COPY_TO_YYLVAL(yytext,length); BEGIN(RULE_PARAMETERS_HEADER); return T_IDENTIFIER; } . BEGIN(INITIAL); REJECT; /* everything else */ } "[:" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); { {Newline} newline(); YYMORE; [^:\n\r]* YYMORE; /* gather everything that's not a colon, and append what comes next */ ":"+[^:\]\n\r]* YYMORE; /* also gather colons that are not followed by colons or newlines */ ":]" { COPY_CODE_TO_YYLVAL(yytext, (yyleng-2)); /* cut off the trailing stuff */ if(rulePosition == RuleLexer) BEGIN(RULE_LEXER); else BEGIN(INITIAL); return T_CODE; } <> { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed code segment..." << endl; yyerror(""); return 0; } } [_A-Z]+ COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; [_a-zA-Z][_a-zA-Z0-9]* COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; [0-9]+ COPY_TO_YYLVAL(yytext,yyleng); return T_NUMBER; {String} { yytext++; /* start inside the quotes */ COPY_TO_YYLVAL(yytext,yyleng-2); /* cut off the trailing quote */ return T_STRING; } . { KDevPG::checkOut << "Unexpected character: ``" << yytext[0] << "''" << endl; yyerror(""); } %% char ch; int yyLine = 1, currentOffset = 0; bool endOfLine = false, yymoreFlag = false; int yyTextLineLeng = 1024; char *yyTextLine = (char*)malloc(yyTextLineLeng); int inp() { if( KDevPG::file.atEnd() ) return EOF; KDevPG::file.getChar( &ch ); return ch; } void newline() { ++yyLine; endOfLine = true; } void countNewlines(const char* code, int leng) { for(int i = 0; i != leng; ++i) if(code[i] == '\n') ++yyLine; } /* initialize the line buffer */ void clearLineBuffer() { yyTextLine[0] = '\0'; currentOffset = 0; endOfLine = false; } struct InitLineBuffer { InitLineBuffer() { clearLineBuffer(); } } _initLineBuffer; /* add the current token to the current line */ void appendLineBuffer() { if (endOfLine == true) clearLineBuffer(); static int lastTextLeng = 0; currentOffset = strlen(yyTextLine); /* start of current */ int newLeng = currentOffset + strlen(yytext) - (yymoreFlag ? lastTextLeng : 0) + 1; if(newLeng > yyTextLineLeng) { do { yyTextLineLeng *= 2; } while(newLeng > yyTextLineLeng); yyTextLine = (char*)realloc(yyTextLine, yyTextLineLeng); } strcpy(yyTextLine+currentOffset, yytext + (yymoreFlag ? lastTextLeng : 0)); /* append current */ /* strcpy is faster than strcat */ Q_ASSERT(strlen(yyTextLine) < size_t(yyTextLineLeng)); lastTextLeng = strlen(yytext); yymoreFlag = false; } void yyerror(const char* msg ) { Q_UNUSED(msg); KDevPG::checkOut << "** LEXICAL ERROR at line " << yyLine << " column " << currentOffset << endl; char *current_end = yyTextLine + strlen(yyTextLine); char *p; /* get the rest of the line if we are not already at the end */ if(!endOfLine) { p = current_end; int c = ch; while(c != EOF && c != '\n') { *p++ = c; c = inp(); } *p++ = '\n'; *p = 0; } /* yyTextLine[] now has the whole line, with the current token */ /* at currentOffset */ /* print error message and current line */ KDevPG::checkOut << yyTextLine; /* print a ^ under the most recent token */ KDevPG::checkOut << QString(currentOffset, ' ').append('^') << endl; /* currentOffset spaces, then ^ */ exit(EXIT_FAILURE); } int yywrap() { return 1; } diff --git a/kdev-pg/kdev-pg-main.cpp b/kdev-pg/kdev-pg-main.cpp index 5ea1b06..0a801e5 100644 --- a/kdev-pg/kdev-pg-main.cpp +++ b/kdev-pg/kdev-pg-main.cpp @@ -1,542 +1,542 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg.h" #include "kdev-pg-ast.h" #include "kdev-pg-visitor.h" #include "kdev-pg-default-visitor.h" #include "kdev-pg-pretty-printer.h" #include "kdev-pg-environment.h" #include "kdev-pg-first.h" #include "kdev-pg-follow.h" #include "kdev-pg-checker.h" #include "kdev-pg-inline-checker.h" #include "kdev-pg-generate.h" #include "kdev-pg-regexp.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { extern QTextStream checkOut; } int yyparse(); void usage() { KDevPG::checkOut << "Usage: kdev-pg-qt [further-options] --output= [further-options] " << endl; } void help() { usage(); KDevPG::checkOut << "Options:" << endl << "\t--output= - Specify a prefix for all generated files" << endl << "\t--namespace= - Specify the namespace for all generated classes (default: the prefix)" << endl << "\t--no-output - Do not actually generate files" << endl << "Components:" << endl << "\t--debug-visitor - Generate a visitor to dump the parse-tree" << endl << "\t--serialize-visitor - Generate a visitor to store the parse-tree in a QTextStream" << endl << "\t--no-ast - Do not generate any AST-files" << endl << "\t--with-ast - Generate AST (default)" << endl << "\t--no-parser - Do not create the parser, built-in-visitors etc." << endl << "\t--with-parser - The default, a parser will be generated" << endl << "\t--no-lexer - Do not generate the lexer" << endl << "\t--with-lexer - Ensure lexer generation" << endl << "\t--token-text - Generate a function converting the number of a token into its name" << endl << "Informative output:" << endl << "\t--terminals - Save a list of all terminals in a file named \"kdev-pg-terminals\"" << endl << "\t--symbols - Save a list of all non-terminals in a file named \"kdev-pg-symbols\"" << endl << "\t--rules - Save debugging-information for all rules in a file named \"kdev-pg-rules\"" << endl << "\t--automata - Save DFAs for all used named regexps in \"kdev-pg-lexer-name-.dot\" and for all states in \"kdev-pg-lexer-state-.dot\"" << endl << "Error-handling:" << endl << "\t--permissive-conflicts - The default, conflicts are shown, but kdev-pg-qt will continue (default)" << endl << "\t--strict-conflicts - Quit after having detected conflicts" << endl << "\t--ignore-conflicts - Do not perform conflict-checking" << endl << "Visitor generation:" << endl << "\t--new-visitor=VisitorName - Create a new empty visitor" << endl << "\t--inherit-default-visitor - Use the DefaultVisitor to visit sub-nodes" << endl << "\t--inherit-abstract-visitor - Reimplement the functionality of the DefaultVisitor" << endl << "Output format:" << endl << "\t--error-aware-code - Line-numbers in parser.cpp related compiler-messages will correspond to line-numbers in the grammar-file (default)" << endl << "\t--beautiful-code - Line-numbers in compiler-messages will be arbitrary, but the code will look more beautiful and it is probably more compiler-independent" << endl << "\t--compatible-error-aware-code - Like --error-aware-code, but using #line instead of GCC-specific directives, thus not providing included-from-info to display the line number in the generated file" << endl << "\t--visitor-table - Visit::visitNode will be implemented by using a lookup-array (default)" << endl << "\t--visitor-switch - Visitor::visitNode will use a switch-statement" << endl << "About:" << endl << "\t--help - Show this messages" << endl << "\t--usage - Show usage" << endl << "\t--version - Show version" << endl << "\t--author - Show authors" << endl << endl << "See http://techbase.kde.org/Development/KDevelop-PG-Qt_Introduction for further aid." << endl; exit(EXIT_SUCCESS); } void version() { KDevPG::checkOut << "KDevelop-PG-Qt: 1.0.0" << endl; exit(EXIT_SUCCESS); } void author() { KDevPG::checkOut << QString::fromUtf8("KDevelop-PG-Qt: Copyright © 2005-2012 by the KDevelop-PG-Qt developers:") << endl << QString::fromUtf8("\tRoberto Raggi\n" "\tJakob Petsovits\n" "\tAndreas Pakulat\n" "\tJonathan Schmidt-Dominé\n" "\t...and others") << endl; exit(EXIT_SUCCESS); } class DebugRule { public: QTextStream& out; DebugRule(QTextStream& o): out(o) {} void operator()(KDevPG::Model::Node *node) { KDevPG::Model::EvolveItem *e = KDevPG::nodeCast(node); out << endl; KDevPG::PrettyPrinter p(out); p(e); bool initial = true; KDevPG::World::NodeSet::iterator it; out << endl; out << " FIRST:["; for (it = KDevPG::globalSystem.first(e).begin(); it != KDevPG::globalSystem.first(e).end(); ++it) { if (!initial) out << ","; p(*it); initial = false; } out << "]"; initial = true; out << endl; out << " FOLLOW:["; for (it = KDevPG::globalSystem.follow(e->mSymbol).begin(); it != KDevPG::globalSystem.follow(e->mSymbol).end(); ++it) { if (!initial) out << ","; p(*it); initial = false; } out << "]"; out << endl; } }; namespace KDevPG { QFileInfo fileInfo; } int main(int argc, char **argv) { bool dump_terminals = false; bool dump_symbols = false; bool generate_parser = true; bool generate_lexer = true; bool ensure_generate_lexer_or_not = false; bool ensure_generate_parser_or_not = false; bool debug_rules = false; bool debug_automata = false; bool inherit_default = false; bool output = true; QString new_visitor; QCoreApplication app(argc, argv); QStringList args = QCoreApplication::arguments(); args.pop_front(); foreach(const QString& arg, args) { #define SW(str) arg.startsWith(QLatin1String(#str)) if (SW(--output=)) { KDevPG::globalSystem.language = arg.mid( 9 ); output = true; } else if (SW(--namespace=)) { KDevPG::globalSystem.ns = arg.mid( 12 ); } else if (arg == "--no-output") { output = false; } else if (arg == "--no-ast") { KDevPG::globalSystem.generateAst = false; } else if (arg == "--with-ast") { KDevPG::globalSystem.generateAst = true; } else if (arg == "--serialize-visitor") { KDevPG::globalSystem.generateSerializeVisitor = true; } else if (arg == "--ignore-conflicts") { KDevPG::globalSystem.conflictHandling = KDevPG::World::Ignore; } else if (arg == "--strict-conflicts") { KDevPG::globalSystem.conflictHandling = KDevPG::World::Strict; } else if (arg == "--permissive-conflicts") { KDevPG::globalSystem.conflictHandling = KDevPG::World::Permissive; } else if (arg == "--debug-visitor") { KDevPG::globalSystem.generateDebugVisitor = true; } else if (arg == "--token-text") { KDevPG::globalSystem.generateTokenText = true; } else if (arg == "--no-parser") { generate_parser = false; ensure_generate_parser_or_not = true; } else if (arg == "--with-parser") { generate_parser = true; ensure_generate_parser_or_not = true; } else if (arg == "--no-lexer") { generate_lexer = false; ensure_generate_lexer_or_not = true; } else if (arg == "--with-lexer") { generate_lexer = true; ensure_generate_lexer_or_not = true; } else if (arg == "--beautiful-code") { KDevPG::globalSystem.lineNumberPolicy = KDevPG::World::BeautifulCode; } else if (arg == "--error-aware-code") { KDevPG::globalSystem.lineNumberPolicy = KDevPG::World::FullLineNumbers; } else if (arg == "--compatible-error-aware-code") { KDevPG::globalSystem.lineNumberPolicy = KDevPG::World::CompatibilityLineNumbers; } else if (arg == "--visitor-table") { KDevPG::globalSystem.visitorTable = true; } else if (arg == "--visitor-switch") { KDevPG::globalSystem.visitorTable = false; } else if (SW(--new-visitor=)) { new_visitor = arg.mid( 14 ); KDevPG::globalSystem.conflictHandling = KDevPG::World::Ignore; output = false; } else if (arg == "--inherit-default-visitor") { inherit_default = true; } else if (arg == "--inherit-abstract-visitor") { inherit_default = false; } else if (arg == "--help") { help(); } else if (arg == "--version") { version(); } else if (arg == "--author") { author(); } else if (arg == "--usage") { usage(); exit(EXIT_SUCCESS); } else if (arg == "--terminals") { dump_terminals = true; } else if (arg == "--symbols") { dump_symbols = true; } else if (arg == "--rules") { debug_rules = true; } else if (arg == "--automata") { debug_automata = true; } else if (KDevPG::file.fileName().isEmpty()) { KDevPG::file.setFileName(arg); if (!KDevPG::file.open(QIODevice::ReadOnly|QIODevice::Text)) { KDevPG::checkOut << "kdev-pg-qt: file ``" << arg << "'' not found!" << endl; KDevPG::file.setFileName(""); } else KDevPG::fileInfo.setFile(KDevPG::file); } else { KDevPG::checkOut << "kdev-pg-qt: unknown option ``" << arg << "''" << endl; } } if( KDevPG::globalSystem.ns.isEmpty() ) KDevPG::globalSystem.ns = KDevPG::globalSystem.language; if( !KDevPG::file.isOpen() ) { exit(1); } yyparse(); KDevPG::file.close(); KDevPG::globalSystem.finishedParsing(); if(!ensure_generate_parser_or_not) generate_parser = !KDevPG::globalSystem.rules.empty(); if(generate_parser) { if(KDevPG::globalSystem.rules.empty()) { KDevPG::checkOut << "** ERROR no parser rules" << endl; KDevPG::ProblemSummaryPrinter::reportError(); } else { if(KDevPG::globalSystem.start.empty()) KDevPG::checkOut << "** WARNING could not detect a start-symbol, every symbol gets reused, you have to care about EOFs yourself!" << endl; for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::InlineChecker check; check(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::InitializeEnvironment initenv; initenv(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::EmptyOperatorChecker check; check(*it); } KDevPG::computeFirst(); KDevPG::computeFollow(); if(KDevPG::globalSystem.conflictHandling != KDevPG::World::Ignore) { for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::FirstFollowConflictChecker check; check(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::FirstFirstConflictChecker check; check(*it); } } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::EmptyFirstChecker check; check(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::EmptyOperatorChecker check; check(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::UndefinedSymbolChecker check; check(*it); } for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { KDevPG::UndefinedTokenChecker check; check(*it); } } } if (ensure_generate_lexer_or_not && generate_lexer && !KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR no lexer definiton" << endl; KDevPG::ProblemSummaryPrinter::reportError(); generate_lexer = false; } if (!ensure_generate_lexer_or_not) generate_lexer = KDevPG::globalSystem.hasLexer; if (generate_lexer) { if(!KDevPG::globalSystem.lexerEnvs.contains("start")) { KDevPG::checkOut << "** ERROR missing start-state in the lexer" << endl; KDevPG::ProblemSummaryPrinter::reportError(); } if(!QRegExp("[a-zA-Z_][a-zA-Z_0-9]*").exactMatch(KDevPG::globalSystem.tokenStream)) { // primarily to exclude KDevPG::TokenStream (the default value) KDevPG::checkOut << "** ERROR You have to specify a valid name for your lexer (%token_stream)" << endl; KDevPG::ProblemSummaryPrinter::reportError(); } foreach(QString state, KDevPG::globalSystem.lexerEnvs.keys()) { KDevPG::GNFA &alltogether = **KDevPG::globalSystem.lexerEnvResults.insert(state, new KDevPG::GNFA(KDevPG::globalSystem.lexerEnvs[state])); KDevPG::GDFA &deterministic = **KDevPG::globalSystem.dfaForNfa.insert(&alltogether, new KDevPG::GDFA(alltogether.dfa())); deterministic.minimize(); deterministic.setActions(KDevPG::globalSystem.lexerActions[state]); } } if(dump_terminals) { QFile ft("kdev-pg-terminals"); ft.open( QIODevice::WriteOnly | QIODevice::Truncate ); QTextStream strm(&ft); for (KDevPG::World::TerminalSet::iterator it = KDevPG::globalSystem.terminals.begin(); it != KDevPG::globalSystem.terminals.end(); ++it) { strm << it.key() << endl; } } if (dump_symbols) { QFile ft("kdev-pg-symbols"); ft.open( QIODevice::WriteOnly | QIODevice::Truncate ); QTextStream strm(&ft); for (KDevPG::World::SymbolSet::iterator it = KDevPG::globalSystem.symbols.begin(); it != KDevPG::globalSystem.symbols.end(); ++it) { strm << it.key() << endl; } } if (debug_rules) { QFile ft("kdev-pg-rules"); ft.open( QIODevice::WriteOnly | QIODevice::Truncate ); QTextStream strm(&ft); for(QList::iterator it = KDevPG::globalSystem.rules.begin(); it != KDevPG::globalSystem.rules.end(); ++it) { DebugRule dr(strm); dr(*it); } } if (debug_automata) { foreach(QString state, KDevPG::globalSystem.lexerEnvs.keys()) { QFile ft(QString("kdev-pg-lexer-state-") + state + ".dot"); ft.open(QIODevice::WriteOnly); QTextStream str(&ft); KDevPG::globalSystem.dfaForNfa[KDevPG::globalSystem.lexerEnvResults[state]]->dotOutput(str, state); ft.close(); } foreach(QString name, KDevPG::globalSystem.regexpById.keys()) { if(KDevPG::globalSystem.dfaForNfa.contains(KDevPG::globalSystem.regexpById[name])) { QFile ft(QString("kdev-pg-lexer-name-") + name + ".dot"); ft.open(QIODevice::WriteOnly); QTextStream str(&ft); KDevPG::globalSystem.dfaForNfa[KDevPG::globalSystem.regexpById[name]]->dotOutput(str, name); ft.close(); } } } KDevPG::ProblemSummaryPrinter()(); if (!(dump_terminals || dump_symbols || debug_rules) && output && KDevPG::globalSystem.language.isEmpty()) { usage(); exit(EXIT_FAILURE); } if (output && generate_parser) KDevPG::generateOutput(); if (output && generate_lexer) KDevPG::generateLexer(); if (!new_visitor.isEmpty()) KDevPG::generateVisitor(new_visitor, inherit_default); return EXIT_SUCCESS; } diff --git a/kdev-pg/kdev-pg-new-visitor-bits-gen.h b/kdev-pg/kdev-pg-new-visitor-bits-gen.h index 63c4ec7..e62a024 100644 --- a/kdev-pg/kdev-pg-new-visitor-bits-gen.h +++ b/kdev-pg/kdev-pg-new-visitor-bits-gen.h @@ -1,47 +1,47 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_NEW_VISITOR_BITS_GEN_H #define KDEV_PG_NEW_VISITOR_BITS_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include +#include +#include namespace KDevPG { class GenerateNewVisitorBitsRule: protected DefaultVisitor { public: QTextStream& out; QString name; public: GenerateNewVisitorBitsRule(QTextStream& o, const QString& n): out(o), name(n) {} void operator()(QPair const &__it); }; } #endif // KDEV_PG_NEW_VISITOR_BITS_GEN_H diff --git a/kdev-pg/kdev-pg-new-visitor-gen.h b/kdev-pg/kdev-pg-new-visitor-gen.h index 2cfe9b1..38a9a77 100644 --- a/kdev-pg/kdev-pg-new-visitor-gen.h +++ b/kdev-pg/kdev-pg-new-visitor-gen.h @@ -1,50 +1,50 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_NEW_VISITOR_GEN_H #define KDEV_PG_NEW_VISITOR_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateNewVisitor { public: QTextStream& out; QString name; public: GenerateNewVisitor(QTextStream& o, const QString& n): out(o), name(n) {} void operator()(); }; } #endif // KDEV_PG_NEW_VISITOR_GEN_H diff --git a/kdev-pg/kdev-pg-parser.cc b/kdev-pg/kdev-pg-parser.cc index 2cfbc87..76123f4 100644 --- a/kdev-pg/kdev-pg-parser.cc +++ b/kdev-pg/kdev-pg-parser.cc @@ -1,3424 +1,3424 @@ /* A Bison parser, made by GNU Bison 2.5. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ /* Line 268 of yacc.c */ #line 2 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg.h" #include "kdev-pg-clone-tree.h" #include "kdev-pg-regexp.h" #include "kdev-pg-unicode-loader.h" #include "kdev-pg-checker.h" -#include +#include #include extern int yylex(); extern void yyerror(const char* msg); extern int yyLine; QString lexerEnv; namespace KDevPG { extern QFile file; extern QTextStream checkOut; } KDevPG::Model::OperatorItem *operatorNode = 0; QString r; /* Line 268 of yacc.c */ #line 119 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-parser.cc" /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_IDENTIFIER = 258, T_ARROW = 259, T_TERMINAL = 260, T_CODE = 261, T_STRING = 262, T_UNQUOTED_STRING = 263, T_NUMBER = 264, T_TOKEN_DECLARATION = 265, T_TOKEN_STREAM_DECLARATION = 266, T_NAMESPACE_DECLARATION = 267, T_PARSERCLASS_DECLARATION = 268, T_LEXERCLASS_DECLARATION = 269, T_PUBLIC = 270, T_PRIVATE = 271, T_PROTECTED = 272, T_DECLARATION = 273, T_BITS = 274, T_CONSTRUCTOR = 275, T_DESTRUCTOR = 276, T_TRY_RECOVER = 277, T_TRY_ROLLBACK = 278, T_CATCH = 279, T_RULE_ARGUMENTS = 280, T_MEMBER = 281, T_TEMPORARY = 282, T_ARGUMENT = 283, T_EXPORT_MACRO = 284, T_NODE = 285, T_NODE_SEQUENCE = 286, T_TOKEN = 287, T_VARIABLE = 288, T_EXPORT_MACRO_HEADER = 289, T_AST_DECLARATION = 290, T_PARSER_DECLARATION_HEADER = 291, T_PARSER_BITS_HEADER = 292, T_AST_HEADER = 293, T_LEXER_DECLARATION_HEADER = 294, T_LEXER_BITS_HEADER = 295, T_PARSER_BASE = 296, T_AST_BASE = 297, T_LEXER_BASE = 298, T_BIN = 299, T_PRE = 300, T_POST = 301, T_TERN = 302, T_LOPR = 303, T_ROPR = 304, T_LEFT_ASSOC = 305, T_RIGHT_ASSOC = 306, T_IS_LEFT_ASSOC = 307, T_IS_RIGHT_ASSOC = 308, T_PRIORITY = 309, T_PAREN = 310, T_INLINE = 311, T_LEXER = 312, T_INPUT_STREAM = 313, T_INPUT_ENCODING = 314, T_TABLE_LEXER = 315, T_SEQUENCE_LEXER = 316, T_NAMED_REGEXP = 317, T_CONTINUE = 318, T_RANGE = 319, T_FAIL = 320, T_LOOKAHEAD = 321, T_BARRIER = 322, T_ENTER_RULE_SET = 323, T_LEAVE_RULE_SET = 324 }; #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 293 of yacc.c */ #line 49 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" KDevPG::Model::Node *item; char* str; KDevPG::Model::VariableDeclarationItem::DeclarationType declarationType; KDevPG::Model::VariableDeclarationItem::StorageType storageType; KDevPG::Model::VariableDeclarationItem::VariableType variableType; KDevPG::Model::Operator *operatorInformation; KDevPG::GNFA *nfa; /* Line 293 of yacc.c */ #line 236 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-parser.cc" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif /* Copy the second part of user declarations. */ /* Line 343 of yacc.c */ #line 248 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-parser.cc" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int yyi) #else static int YYID (yyi) int yyi; #endif { return yyi; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 394 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 89 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 60 /* YYNRULES -- Number of rules. */ #define YYNRULES 178 /* YYNRULES -- Number of states. */ #define YYNSTATES 350 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 324 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 2, 2, 74, 2, 71, 72, 79, 80, 84, 2, 83, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 10, 2, 87, 2, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 2, 82, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 76, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 4, 10, 12, 15, 18, 24, 27, 33, 37, 39, 41, 44, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 82, 85, 88, 89, 96, 97, 103, 104, 111, 112, 119, 120, 131, 132, 143, 144, 149, 150, 155, 156, 161, 162, 164, 166, 167, 171, 173, 177, 179, 183, 185, 188, 191, 193, 196, 198, 202, 204, 207, 210, 212, 216, 220, 222, 224, 226, 228, 229, 233, 235, 239, 241, 245, 247, 250, 253, 255, 258, 260, 264, 266, 269, 272, 274, 278, 282, 284, 286, 288, 290, 292, 293, 299, 305, 311, 316, 321, 323, 328, 332, 339, 340, 344, 346, 350, 352, 354, 357, 361, 366, 369, 371, 376, 385, 386, 388, 390, 392, 394, 397, 400, 402, 405, 407, 411, 414, 416, 418, 421, 423, 427, 429, 433, 441, 449, 454, 455, 458, 459, 461, 464, 465, 475, 485, 492, 497, 503, 507, 511, 516, 520, 522, 524, 527, 529, 531, 534, 537, 542, 546, 549, 551, 553, 556, 563, 569, 577, 584, 585, 587, 589, 591, 593 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 90, 0, -1, -1, 137, 91, 92, 123, 137, -1, 93, -1, 92, 93, -1, 14, 121, -1, 14, 71, 20, 72, 6, -1, 15, 121, -1, 15, 71, 20, 72, 6, -1, 11, 122, 10, -1, 61, -1, 62, -1, 60, 7, -1, 12, 3, 10, -1, 30, 7, -1, 35, 7, -1, 13, 6, -1, 36, 6, -1, 37, 7, -1, 38, 7, -1, 39, 7, -1, 40, 7, -1, 59, 7, -1, 41, 7, -1, 43, 3, 7, -1, 42, 7, -1, 44, 7, -1, -1, 58, 7, 94, 4, 96, 10, -1, -1, 58, 95, 4, 96, 10, -1, -1, 105, 4, 3, 10, 97, 96, -1, -1, 105, 137, 104, 10, 98, 96, -1, -1, 105, 67, 71, 105, 72, 137, 104, 10, 99, 96, -1, -1, 105, 68, 71, 105, 72, 137, 104, 10, 100, 96, -1, -1, 66, 6, 101, 96, -1, -1, 69, 6, 102, 96, -1, -1, 70, 6, 103, 96, -1, -1, 5, -1, 64, -1, -1, 105, 73, 106, -1, 106, -1, 106, 74, 107, -1, 107, -1, 108, 75, 107, -1, 108, -1, 76, 108, -1, 77, 108, -1, 109, -1, 109, 110, -1, 110, -1, 110, 78, 111, -1, 111, -1, 111, 79, -1, 111, 80, -1, 112, -1, 71, 105, 72, -1, 81, 113, 82, -1, 83, -1, 7, -1, 8, -1, 63, -1, -1, 113, 73, 114, -1, 114, -1, 114, 74, 115, -1, 115, -1, 116, 75, 115, -1, 116, -1, 76, 116, -1, 77, 116, -1, 117, -1, 117, 118, -1, 118, -1, 118, 78, 119, -1, 119, -1, 119, 79, -1, 119, 80, -1, 120, -1, 71, 105, 72, -1, 81, 113, 82, -1, 83, -1, 7, -1, 65, -1, 8, -1, 63, -1, -1, 71, 16, 19, 72, 6, -1, 71, 18, 19, 72, 6, -1, 71, 17, 19, 72, 6, -1, 71, 21, 72, 6, -1, 71, 22, 72, 6, -1, 5, -1, 5, 71, 7, 72, -1, 122, 84, 5, -1, 122, 84, 5, 71, 7, 72, -1, -1, 123, 135, 10, -1, 85, -1, 71, 134, 72, -1, 126, -1, 125, -1, 57, 3, -1, 128, 129, 125, -1, 86, 128, 129, 125, -1, 3, 127, -1, 5, -1, 23, 71, 134, 72, -1, 24, 71, 134, 72, 25, 71, 134, 72, -1, -1, 26, -1, 3, -1, 87, -1, 88, -1, 124, 80, -1, 124, 79, -1, 124, -1, 77, 124, -1, 130, -1, 131, 78, 124, -1, 131, 6, -1, 6, -1, 131, -1, 132, 131, -1, 132, -1, 77, 6, 132, -1, 133, -1, 134, 73, 133, -1, 134, 4, 3, 6, 81, 144, 82, -1, 134, 4, 3, 81, 144, 82, 137, -1, 134, 4, 3, 137, -1, -1, 136, 139, -1, -1, 6, -1, 140, 138, -1, -1, 49, 125, 138, 50, 3, 81, 144, 82, 137, -1, 49, 125, 138, 50, 3, 6, 81, 144, 82, -1, 49, 125, 138, 50, 3, 137, -1, 45, 143, 141, 142, -1, 48, 143, 143, 141, 142, -1, 46, 143, 141, -1, 47, 143, 141, -1, 47, 143, 141, 142, -1, 56, 143, 143, -1, 85, -1, 9, -1, 55, 6, -1, 51, -1, 52, -1, 53, 6, -1, 54, 6, -1, 77, 6, 5, 6, -1, 77, 6, 5, -1, 5, 6, -1, 5, -1, 145, -1, 144, 145, -1, 146, 147, 148, 3, 88, 3, -1, 146, 147, 33, 3, 10, -1, 146, 147, 148, 86, 3, 88, 3, -1, 146, 147, 33, 86, 3, 10, -1, -1, 29, -1, 27, -1, 28, -1, 31, -1, 34, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 94, 94, 94, 101, 102, 106, 108, 110, 112, 114, 115, 129, 143, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 198, 199, 199, 204, 203, 207, 206, 217, 216, 249, 248, 291, 290, 295, 294, 299, 298, 302, 306, 309, 312, 316, 317, 321, 322, 326, 327, 331, 332, 333, 337, 338, 342, 343, 347, 348, 349, 353, 354, 355, 356, 357, 358, 373, 377, 378, 382, 383, 387, 388, 392, 393, 394, 398, 399, 403, 404, 408, 409, 410, 414, 415, 416, 417, 418, 441, 442, 457, 462, 464, 466, 468, 470, 475, 476, 477, 478, 482, 484, 488, 489, 490, 491, 492, 493, 494, 498, 499, 503, 508, 515, 516, 520, 530, 531, 535, 536, 537, 538, 542, 543, 548, 549, 553, 554, 558, 559, 563, 564, 568, 573, 578, 580, 580, 590, 591, 596, 597, 601, 609, 617, 628, 629, 630, 631, 632, 633, 637, 638, 639, 643, 644, 645, 652, 662, 663, 664, 665, 669, 670, 682, 684, 686, 688, 693, 694, 698, 699, 703, 704 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "T_IDENTIFIER", "T_ARROW", "T_TERMINAL", "T_CODE", "T_STRING", "T_UNQUOTED_STRING", "T_NUMBER", "';'", "T_TOKEN_DECLARATION", "T_TOKEN_STREAM_DECLARATION", "T_NAMESPACE_DECLARATION", "T_PARSERCLASS_DECLARATION", "T_LEXERCLASS_DECLARATION", "T_PUBLIC", "T_PRIVATE", "T_PROTECTED", "T_DECLARATION", "T_BITS", "T_CONSTRUCTOR", "T_DESTRUCTOR", "T_TRY_RECOVER", "T_TRY_ROLLBACK", "T_CATCH", "T_RULE_ARGUMENTS", "T_MEMBER", "T_TEMPORARY", "T_ARGUMENT", "T_EXPORT_MACRO", "T_NODE", "T_NODE_SEQUENCE", "T_TOKEN", "T_VARIABLE", "T_EXPORT_MACRO_HEADER", "T_AST_DECLARATION", "T_PARSER_DECLARATION_HEADER", "T_PARSER_BITS_HEADER", "T_AST_HEADER", "T_LEXER_DECLARATION_HEADER", "T_LEXER_BITS_HEADER", "T_PARSER_BASE", "T_AST_BASE", "T_LEXER_BASE", "T_BIN", "T_PRE", "T_POST", "T_TERN", "T_LOPR", "T_ROPR", "T_LEFT_ASSOC", "T_RIGHT_ASSOC", "T_IS_LEFT_ASSOC", "T_IS_RIGHT_ASSOC", "T_PRIORITY", "T_PAREN", "T_INLINE", "T_LEXER", "T_INPUT_STREAM", "T_INPUT_ENCODING", "T_TABLE_LEXER", "T_SEQUENCE_LEXER", "T_NAMED_REGEXP", "T_CONTINUE", "T_RANGE", "T_FAIL", "T_LOOKAHEAD", "T_BARRIER", "T_ENTER_RULE_SET", "T_LEAVE_RULE_SET", "'('", "')'", "'|'", "'&'", "'^'", "'~'", "'?'", "'@'", "'*'", "'+'", "'['", "']'", "'.'", "','", "'0'", "'#'", "'='", "':'", "$accept", "system", "$@1", "declarations", "declaration", "$@2", "$@3", "lexer_declaration_rest", "$@4", "$@5", "$@6", "$@7", "$@8", "$@9", "$@10", "opt_lexer_action", "regexp", "regexp1", "regexp2", "regexp3", "regexp4", "regexp5", "regexp6", "regexp7", "aregexp", "aregexp1", "aregexp2", "aregexp3", "aregexp4", "aregexp5", "aregexp6", "aregexp7", "member_declaration_rest", "declared_tokens", "rules", "primary_item", "primary_atom", "try_item", "rule_arguments_opt", "name", "scope", "unary_item", "postfix_item", "item_sequence", "conditional_item", "option_item", "item", "$@11", "code_opt", "operatorDeclarations", "operatorRule", "operatorDeclaration", "priority", "assoc", "operator", "variableDeclarations", "variableDeclaration", "declarationType_opt", "storageType", "variableType", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 59, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 40, 41, 124, 38, 94, 126, 63, 64, 42, 43, 91, 93, 46, 44, 48, 35, 61, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 89, 91, 90, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 93, 95, 93, 97, 96, 98, 96, 99, 96, 100, 96, 101, 96, 102, 96, 103, 96, 96, 104, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 108, 109, 109, 110, 110, 111, 111, 111, 112, 112, 112, 112, 112, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 116, 117, 117, 118, 118, 119, 119, 119, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 122, 122, 122, 122, 123, 123, 124, 124, 124, 124, 124, 124, 124, 125, 125, 126, 126, 127, 127, 128, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 135, 136, 135, 137, 137, 138, 138, 139, 139, 139, 140, 140, 140, 140, 140, 140, 141, 141, 141, 142, 142, 142, 142, 143, 143, 143, 143, 144, 144, 145, 145, 145, 145, 146, 146, 147, 147, 148, 148 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 5, 1, 2, 2, 5, 2, 5, 3, 1, 1, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 0, 6, 0, 5, 0, 6, 0, 6, 0, 10, 0, 10, 0, 4, 0, 4, 0, 4, 0, 1, 1, 0, 3, 1, 3, 1, 3, 1, 2, 2, 1, 2, 1, 3, 1, 2, 2, 1, 3, 3, 1, 1, 1, 1, 0, 3, 1, 3, 1, 3, 1, 2, 2, 1, 2, 1, 3, 1, 2, 2, 1, 3, 3, 1, 1, 1, 1, 1, 0, 5, 5, 5, 4, 4, 1, 4, 3, 6, 0, 3, 1, 3, 1, 1, 2, 3, 4, 2, 1, 4, 8, 0, 1, 1, 1, 1, 2, 2, 1, 2, 1, 3, 2, 1, 1, 2, 1, 3, 1, 3, 7, 7, 4, 0, 2, 0, 1, 2, 0, 9, 9, 6, 4, 5, 3, 3, 4, 3, 1, 1, 2, 1, 1, 2, 2, 4, 3, 2, 1, 1, 2, 6, 5, 7, 6, 0, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 143, 144, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 12, 106, 4, 102, 0, 0, 17, 0, 6, 0, 8, 15, 16, 18, 19, 20, 21, 22, 24, 26, 0, 27, 28, 0, 23, 13, 5, 141, 0, 10, 0, 14, 0, 0, 0, 0, 0, 0, 0, 25, 0, 72, 119, 116, 131, 0, 0, 0, 0, 0, 108, 0, 126, 111, 110, 0, 128, 132, 134, 136, 0, 0, 0, 3, 0, 104, 0, 0, 0, 0, 0, 0, 0, 72, 69, 70, 71, 0, 0, 0, 72, 72, 72, 96, 68, 0, 143, 51, 53, 55, 58, 60, 62, 65, 120, 115, 0, 0, 112, 131, 0, 0, 127, 121, 0, 125, 124, 122, 123, 0, 130, 0, 0, 133, 0, 0, 107, 0, 142, 103, 0, 0, 0, 0, 7, 100, 101, 9, 0, 40, 42, 44, 0, 56, 57, 92, 94, 95, 93, 72, 96, 96, 96, 91, 0, 74, 76, 78, 81, 83, 85, 88, 31, 0, 0, 0, 72, 49, 72, 72, 59, 72, 63, 64, 0, 0, 109, 135, 0, 119, 113, 129, 143, 137, 146, 0, 97, 99, 98, 29, 72, 72, 72, 66, 0, 79, 80, 0, 96, 67, 96, 96, 82, 96, 86, 87, 0, 72, 72, 50, 47, 48, 0, 52, 54, 61, 117, 0, 114, 144, 173, 140, 0, 0, 0, 0, 0, 0, 146, 105, 41, 43, 45, 89, 90, 73, 75, 77, 84, 32, 0, 0, 34, 0, 173, 174, 173, 167, 0, 166, 0, 0, 0, 0, 0, 0, 0, 145, 72, 143, 143, 72, 0, 173, 143, 168, 175, 176, 0, 165, 0, 157, 0, 156, 0, 152, 153, 0, 155, 143, 33, 49, 49, 35, 0, 138, 139, 177, 0, 178, 0, 164, 158, 159, 160, 0, 0, 150, 154, 0, 144, 173, 149, 0, 0, 118, 0, 0, 0, 0, 163, 161, 162, 151, 173, 173, 36, 38, 170, 0, 0, 0, 173, 143, 72, 72, 172, 169, 0, 148, 147, 37, 39, 171 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 2, 5, 27, 28, 66, 49, 111, 274, 277, 340, 341, 206, 207, 208, 228, 112, 113, 114, 115, 116, 117, 118, 119, 170, 171, 172, 173, 174, 175, 176, 177, 34, 30, 53, 78, 79, 80, 121, 81, 135, 82, 83, 84, 85, 86, 87, 88, 3, 243, 144, 244, 290, 313, 267, 262, 263, 264, 284, 306 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -258 static const yytype_int16 yypact[] = { 12, -258, 21, -258, -258, 236, 19, 28, 51, 9, 15, 59, 63, 72, 91, 125, 133, 155, 164, 166, 119, 169, 184, 200, 205, -258, -258, 236, -258, 56, 34, 142, -258, 267, -258, 283, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, 221, -258, -258, 139, -258, -258, -258, 6, 238, -258, 194, -258, 170, 206, 295, 185, 230, 243, 244, -258, 313, 65, 42, -258, 318, 248, 249, 319, 10, 22, -258, 320, 88, -258, -258, 116, -258, 26, 17, -258, 43, 311, 275, -258, 253, 255, 256, 257, 258, 321, 325, 326, 327, 65, -258, -258, -258, 328, 329, 330, 143, 143, 143, 98, -258, 331, 192, 263, -258, 264, 130, 260, 136, -258, -258, -258, 10, 10, -258, -258, 145, 17, -258, -258, 116, -258, -258, -258, -258, 50, -258, 14, 14, 26, 337, 10, -258, 50, -258, -258, 335, 338, 339, 340, -258, -258, -258, -258, 333, -258, -258, -258, 162, -258, -258, -258, -258, -258, -258, 143, 98, 98, 98, -258, -34, 273, -258, 274, 107, 270, 157, -258, -258, 347, 280, 281, 143, 0, 143, 143, 260, 158, -258, -258, 180, 182, -258, 17, 50, 332, -258, -258, 20, -258, 108, 282, -258, -258, -258, -258, 65, 65, 65, -258, 191, -258, -258, -17, 98, -258, 98, 98, 270, 175, -258, -258, 343, 143, 143, 263, -258, -258, 345, -258, -258, 136, -258, 334, -258, 276, 336, -258, 5, 5, 5, 5, 5, 306, 108, -258, -258, -258, -258, -258, -258, 273, -258, -258, 157, -258, 195, 197, -258, 289, 336, -258, 7, -258, 254, 355, 356, -1, -1, -1, 5, 5, 360, -258, 65, 12, 12, 65, 10, 115, 12, -258, -258, -258, 161, -258, 359, -258, 361, -258, 106, -258, 106, -1, -258, 36, -258, 0, 0, -258, 218, -258, -258, -258, 4, -258, 11, 362, -258, -258, -258, 363, 364, -258, -258, 106, 285, 336, -258, 365, 366, -258, 367, 368, 284, 370, -258, -258, -258, -258, 336, 118, -258, -258, -258, 369, 371, 290, 120, 12, 65, 65, -258, -258, 377, -258, -258, -258, -258, -258 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -258, -258, -258, -258, 354, -258, -258, -97, -258, -258, -258, -258, -258, -258, -258, -5, -103, 202, 122, 201, -258, 266, 196, -258, 217, 172, 94, 146, -258, 213, 171, -258, 378, -258, -258, -14, -10, -258, -258, 312, 261, -258, -80, 265, 252, -73, -258, -258, -53, 150, -258, -258, -217, -257, -9, -191, -219, -258, -258, -258 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -145 static const yytype_int16 yytable[] = { 89, 126, 154, 158, 139, 226, -143, 322, 287, 68, 265, 69, 70, 68, 324, 69, 125, 68, 1, 69, 68, 4, 69, 125, 29, 68, 235, 69, 127, 71, 72, 31, 136, 71, 72, 314, 261, 71, 72, 214, 71, 72, 316, 281, 55, 71, 72, 140, 215, 190, 191, 291, 292, 195, 288, 69, 214, 32, 329, 183, 281, 128, 210, 73, 227, 250, 37, 73, 120, 279, 38, 73, 100, 101, 73, -46, 315, 74, 39, 73, 33, 74, 266, 75, 289, 74, 35, 75, 74, 280, 323, 76, 77, 74, 138, 76, 77, 325, 40, 76, 77, 236, 76, 77, 137, 161, 162, 76, 77, 246, 247, 248, 281, 139, 161, 162, 141, 317, 56, 281, 256, 257, 46, 197, 128, 196, 331, 54, 102, -121, -121, 103, 41, 200, 104, 105, 106, 100, 101, 338, 42, 107, 108, 67, 261, 237, 109, 261, 110, 261, 100, 101, 57, 238, 239, 240, 241, 309, 310, 311, 312, 163, 43, 164, 242, 100, 101, 131, 132, 165, 163, 44, 164, 45, 166, 167, 47, 296, 165, 168, 299, 169, 161, 162, 234, -96, -96, -96, 168, 92, 169, 48, 303, 102, 304, 305, 179, 301, 1, 91, 339, 106, 345, 133, 134, 300, 102, 50, -72, -72, -72, 109, 51, 110, 106, 188, 189, 192, 141, 107, 108, 102, 297, 298, 109, 93, 110, 302, 65, 106, 268, 269, 270, 271, 209, 182, 220, 221, 163, 109, 164, 110, 318, 347, 348, 90, 165, 6, 7, 8, 9, 10, 232, 141, 233, 141, 168, 95, 169, 180, 181, 293, 294, 249, 182, 182, 11, 275, 182, 276, 182, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 282, 283, 58, 59, 60, 346, 61, 62, 63, 321, 141, 319, 320, 22, 23, 24, 25, 26, 58, 59, 60, 96, 64, 62, 63, 229, 230, 159, 160, 252, 253, 211, 212, 94, 97, 98, 99, -144, 122, 123, 142, 124, 129, 143, 145, 146, 150, 147, 148, 149, 151, 152, 153, 155, 156, 157, 184, 187, 185, 198, 178, 201, 205, 202, 203, 204, 216, 219, 217, 222, 223, 224, 255, 245, 258, 272, 260, 120, 259, 278, 285, 286, 295, 307, 261, 330, 308, 326, 327, 328, 335, 336, 337, 343, 332, 333, 334, 344, 342, 349, 52, 186, 231, 225, 213, 251, 218, 36, 130, 254, 194, 193, 199, 273 }; #define yypact_value_is_default(yystate) \ ((yystate) == (-258)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_uint16 yycheck[] = { 53, 74, 99, 106, 84, 5, 0, 3, 9, 3, 5, 5, 6, 3, 3, 5, 6, 3, 6, 5, 3, 0, 5, 6, 5, 3, 6, 5, 6, 23, 24, 3, 6, 23, 24, 292, 29, 23, 24, 73, 23, 24, 6, 262, 10, 23, 24, 4, 82, 122, 123, 268, 269, 3, 55, 5, 73, 6, 315, 112, 279, 75, 165, 57, 64, 82, 7, 57, 26, 260, 7, 57, 7, 8, 57, 10, 293, 71, 6, 57, 71, 71, 77, 77, 85, 71, 71, 77, 71, 82, 86, 85, 86, 71, 77, 85, 86, 86, 7, 85, 86, 81, 85, 86, 78, 7, 8, 85, 86, 206, 207, 208, 331, 193, 7, 8, 73, 81, 84, 338, 223, 224, 3, 137, 138, 135, 317, 71, 63, 87, 88, 66, 7, 143, 69, 70, 71, 7, 8, 330, 7, 76, 77, 4, 29, 198, 81, 29, 83, 29, 7, 8, 10, 45, 46, 47, 48, 51, 52, 53, 54, 63, 7, 65, 56, 7, 8, 79, 80, 71, 63, 7, 65, 7, 76, 77, 7, 274, 71, 81, 277, 83, 7, 8, 194, 78, 79, 80, 81, 19, 83, 7, 31, 63, 33, 34, 4, 82, 6, 5, 82, 71, 82, 87, 88, 278, 63, 7, 78, 79, 80, 81, 7, 83, 71, 79, 80, 72, 73, 76, 77, 63, 275, 276, 81, 19, 83, 280, 7, 71, 239, 240, 241, 242, 72, 73, 79, 80, 63, 81, 65, 83, 295, 340, 341, 7, 71, 11, 12, 13, 14, 15, 72, 73, 72, 73, 81, 72, 83, 67, 68, 270, 271, 72, 73, 73, 30, 72, 73, 72, 73, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 27, 28, 16, 17, 18, 339, 20, 21, 22, 72, 73, 297, 298, 58, 59, 60, 61, 62, 16, 17, 18, 72, 20, 21, 22, 184, 185, 107, 108, 216, 217, 166, 167, 19, 72, 72, 4, 0, 71, 71, 10, 3, 3, 49, 72, 71, 6, 72, 72, 72, 6, 6, 6, 6, 6, 6, 74, 78, 75, 3, 10, 7, 10, 6, 6, 6, 74, 78, 75, 3, 71, 71, 10, 72, 10, 50, 81, 26, 25, 71, 6, 6, 3, 5, 29, 81, 6, 6, 6, 6, 3, 88, 3, 3, 10, 10, 10, 88, 10, 3, 27, 116, 187, 182, 168, 214, 174, 10, 77, 219, 130, 127, 141, 244 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 6, 90, 137, 0, 91, 11, 12, 13, 14, 15, 30, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 58, 59, 60, 61, 62, 92, 93, 5, 122, 3, 6, 71, 121, 71, 121, 7, 7, 6, 7, 7, 7, 7, 7, 7, 3, 7, 7, 95, 7, 7, 93, 123, 71, 10, 84, 10, 16, 17, 18, 20, 21, 22, 20, 7, 94, 4, 3, 5, 6, 23, 24, 57, 71, 77, 85, 86, 124, 125, 126, 128, 130, 131, 132, 133, 134, 135, 136, 137, 7, 5, 19, 19, 19, 72, 72, 72, 72, 4, 7, 8, 63, 66, 69, 70, 71, 76, 77, 81, 83, 96, 105, 106, 107, 108, 109, 110, 111, 112, 26, 127, 71, 71, 3, 6, 134, 6, 124, 3, 128, 79, 80, 87, 88, 129, 6, 78, 77, 131, 4, 73, 10, 49, 139, 72, 71, 72, 72, 72, 6, 6, 6, 6, 96, 6, 6, 6, 105, 108, 108, 7, 8, 63, 65, 71, 76, 77, 81, 83, 113, 114, 115, 116, 117, 118, 119, 120, 10, 4, 67, 68, 73, 137, 74, 75, 110, 78, 79, 80, 134, 134, 72, 132, 129, 3, 125, 124, 3, 133, 125, 7, 6, 6, 6, 10, 101, 102, 103, 72, 105, 116, 116, 113, 73, 82, 74, 75, 118, 78, 79, 80, 3, 71, 71, 106, 5, 64, 104, 107, 107, 111, 72, 72, 125, 6, 81, 137, 45, 46, 47, 48, 56, 138, 140, 72, 96, 96, 96, 72, 82, 114, 115, 115, 119, 10, 105, 105, 10, 25, 81, 29, 144, 145, 146, 5, 77, 143, 143, 143, 143, 143, 50, 138, 97, 72, 72, 98, 71, 144, 82, 145, 27, 28, 147, 6, 6, 9, 55, 85, 141, 141, 141, 143, 143, 3, 96, 137, 137, 96, 134, 82, 137, 31, 33, 34, 148, 5, 6, 51, 52, 53, 54, 142, 142, 141, 6, 81, 137, 104, 104, 72, 3, 86, 3, 86, 6, 6, 6, 142, 81, 144, 10, 10, 10, 3, 88, 3, 144, 82, 99, 100, 10, 3, 88, 82, 137, 96, 96, 3 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. However, YYFAIL appears to be in use. Nevertheless, it is formally deprecated in Bison 2.4.2's NEWS entry, where a plan to phase it out is discussed. */ #define YYFAIL goto yyerrlab #if defined YYFAIL /* This is here to suppress warnings from the GCC cpp's -Wunused-macros. Normally we don't worry about that warning, but some users do, and we want to make it easy for users to remove YYFAIL uses, which will produce warnings from Bison 2.5. */ #endif #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void yy_stack_print (yybottom, yytop) yytype_int16 *yybottom; yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule) #else static void yy_reduce_print (yyvsp, yyrule) YYSTYPE *yyvsp; int yyrule; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = 0; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - Assume YYFAIL is not used. It's too flawed to consider. See for details. YYERROR is fine as it does not invoke this function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yymsg, yytype, yyvaluep) const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void) #else int yyparse () #endif #endif { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: `yyss': related to states. `yyvs': related to semantic values. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yytoken = 0; yyss = yyssa; yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* Line 1806 of yacc.c */ #line 94 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.decl = (yyvsp[(1) - (1)].str); } break; case 3: /* Line 1806 of yacc.c */ #line 97 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.bits += (yyvsp[(5) - (5)].str); } break; case 6: /* Line 1806 of yacc.c */ #line 107 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushParserClassMember((yyvsp[(2) - (2)].item)); } break; case 7: /* Line 1806 of yacc.c */ #line 109 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.bits += (yyvsp[(5) - (5)].str); } break; case 8: /* Line 1806 of yacc.c */ #line 111 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushLexerClassMember((yyvsp[(2) - (2)].item)); } break; case 9: /* Line 1806 of yacc.c */ #line 113 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.lexerBits += (yyvsp[(5) - (5)].str); } break; case 11: /* Line 1806 of yacc.c */ #line 116 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%table_lexer) before any lexer rules"; exit(-1); } switch(KDevPG::GDFA::type) { case KDevPG::SAscii: KDevPG::GDFA::type = KDevPG::TAscii; break; case KDevPG::SLatin1: KDevPG::GDFA::type = KDevPG::TLatin1; break; case KDevPG::SUtf8: KDevPG::GDFA::type = KDevPG::TUtf8; break; case KDevPG::SUcs2: KDevPG::GDFA::type = KDevPG::TUcs2; break; case KDevPG::SUtf16: KDevPG::GDFA::type = KDevPG::TUtf16; break; /* case KDevPG::SUcs4: KDevPG::GDFA::type = KDevPG::TUcs4; break; */ default: /* empty */; } } break; case 12: /* Line 1806 of yacc.c */ #line 130 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } switch(KDevPG::GDFA::type) { case KDevPG::TAscii: KDevPG::GDFA::type = KDevPG::SAscii; break; case KDevPG::TLatin1: KDevPG::GDFA::type = KDevPG::SLatin1; break; case KDevPG::TUtf8: KDevPG::GDFA::type = KDevPG::SUtf8; break; case KDevPG::TUcs2: KDevPG::GDFA::type = KDevPG::SUcs2; break; case KDevPG::TUtf16: KDevPG::GDFA::type = KDevPG::SUtf16; break; /* case KDevPG::TUcs4: KDevPG::GDFA::type = KDevPG::SUcs4; break; */ default: /* empty */; } } break; case 13: /* Line 1806 of yacc.c */ #line 144 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } int base = (KDevPG::GDFA::type / 4) * 4; // warning: magic constant: number of different codecs QString str = (yyvsp[(2) - (2)].str); str = str.toLower(); str.replace('-', ""); if(str == "ascii") /* base += 0*/; else if(str == "latin1") base += 1; else if(str == "utf8") base += 2; else if(str == "ucs2") base += 3; else if(str == "utf16") base += 4; else if(str == "ucs4" || str == "utf32") base += 5; else { KDevPG::checkOut << "** ERROR unknown codec ``" << (yyvsp[(2) - (2)].str) << "''" << endl; exit(-1); } KDevPG::GDFA::type = KDevPG::AutomatonType(base); } break; case 14: /* Line 1806 of yacc.c */ #line 171 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.tokenStream = (yyvsp[(2) - (3)].str); } break; case 15: /* Line 1806 of yacc.c */ #line 173 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.exportMacro = (yyvsp[(2) - (2)].str); } break; case 16: /* Line 1806 of yacc.c */ #line 175 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.exportMacroHeader = (yyvsp[(2) - (2)].str); } break; case 17: /* Line 1806 of yacc.c */ #line 177 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.namespaceCode = (yyvsp[(2) - (2)].str); } break; case 18: /* Line 1806 of yacc.c */ #line 179 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.astCode = (yyvsp[(2) - (2)].str); } break; case 19: /* Line 1806 of yacc.c */ #line 181 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushParserDeclarationHeader((yyvsp[(2) - (2)].str)); } break; case 20: /* Line 1806 of yacc.c */ #line 183 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushParserBitsHeader((yyvsp[(2) - (2)].str)); } break; case 21: /* Line 1806 of yacc.c */ #line 185 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushAstHeader((yyvsp[(2) - (2)].str)); } break; case 22: /* Line 1806 of yacc.c */ #line 187 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushLexerDeclarationHeader((yyvsp[(2) - (2)].str)); } break; case 23: /* Line 1806 of yacc.c */ #line 189 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.inputStream = (yyvsp[(2) - (2)].str); } break; case 24: /* Line 1806 of yacc.c */ #line 191 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushLexerBitsHeader((yyvsp[(2) - (2)].str)); } break; case 25: /* Line 1806 of yacc.c */ #line 193 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.astBaseClasses[(yyvsp[(2) - (3)].str)] = (yyvsp[(3) - (3)].str); } break; case 26: /* Line 1806 of yacc.c */ #line 195 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.parserBaseClass = (yyvsp[(2) - (2)].str); } break; case 27: /* Line 1806 of yacc.c */ #line 197 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.lexerBaseClass = (yyvsp[(2) - (2)].str); } break; case 28: /* Line 1806 of yacc.c */ #line 198 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.hasLexer = true; lexerEnv = (yyvsp[(2) - (2)].str); if(KDevPG::globalSystem.lexerActions[lexerEnv].empty()) KDevPG::globalSystem.lexerActions[lexerEnv].push_back("qDebug() << \"error\"; exit(-1);"); } break; case 30: /* Line 1806 of yacc.c */ #line 199 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.hasLexer = true; KDevPG::loadUnicodeData(); lexerEnv = "start"; if(KDevPG::globalSystem.lexerActions["start"].empty()) KDevPG::globalSystem.lexerActions["start"].push_back("qDebug() << \"error\"; exit(-1);"); } break; case 32: /* Line 1806 of yacc.c */ #line 204 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.regexpById[(yyvsp[(3) - (4)].str)] = (yyvsp[(1) - (4)].nfa); } break; case 34: /* Line 1806 of yacc.c */ #line 207 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if((yyvsp[(1) - (4)].nfa)->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if((yyvsp[(1) - (4)].nfa)->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; QString s = QString((yyvsp[(2) - (4)].str)) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back((yyvsp[(1) - (4)].nfa)); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } break; case 36: /* Line 1806 of yacc.c */ #line 217 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if((yyvsp[(1) - (8)].nfa)->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if((yyvsp[(1) - (8)].nfa)->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; bool ignore = false; auto minLen = (yyvsp[(4) - (8)].nfa)->minLength(), maxLen = (yyvsp[(4) - (8)].nfa)->maxLength(); if(minLen == 0) { KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-lookahead at line " << yyLine << ", ignore the lookahead." << endl; ignore = true; } else if(minLen != maxLen) { KDevPG::checkOut << "** WARNING Invalid lookahead (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the lookahead." << endl; ignore = true; } if(ignore) { QString s = QString((yyvsp[(6) - (8)].str)) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back((yyvsp[(1) - (8)].nfa)); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } else { QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString((yyvsp[(6) - (8)].str)) + QString(r); *(yyvsp[(1) - (8)].nfa) <<= *(yyvsp[(4) - (8)].nfa); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back((yyvsp[(1) - (8)].nfa)); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } } break; case 38: /* Line 1806 of yacc.c */ #line 249 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if((yyvsp[(1) - (8)].nfa)->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if((yyvsp[(1) - (8)].nfa)->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; bool ignore = false; auto minLen = (yyvsp[(4) - (8)].nfa)->minLength(), maxLen = (yyvsp[(4) - (8)].nfa)->maxLength(); if(minLen == 0) { KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-barrier at line " << yyLine << ", ignore the barrier." << endl; ignore = true; } else if(minLen != maxLen) { KDevPG::checkOut << "** WARNING Invalid barrier (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the barrier." << endl; ignore = true; } if(ignore) { QString s = QString((yyvsp[(6) - (8)].str)) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back((yyvsp[(1) - (8)].nfa)); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } else { KDevPG::GNFA exclude = KDevPG::GNFA::anything(); exclude <<= *(yyvsp[(4) - (8)].nfa); exclude <<= KDevPG::GNFA::anything(); KDevPG::GNFA *staying = new KDevPG::GNFA(*(yyvsp[(1) - (8)].nfa)); *staying ^= exclude; KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back(staying); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(QString((yyvsp[(6) - (8)].str)) + QString(r)); // barrier should not get read partially exclude <<= KDevPG::GNFA::anyChar(); *(yyvsp[(1) - (8)].nfa) <<= *(yyvsp[(4) - (8)].nfa); *(yyvsp[(1) - (8)].nfa) ^= exclude; QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString((yyvsp[(6) - (8)].str)) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back((yyvsp[(1) - (8)].nfa)); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } } break; case 40: /* Line 1806 of yacc.c */ #line 291 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.lexerActions[lexerEnv][0] = QString((yyvsp[(2) - (2)].str)); } break; case 42: /* Line 1806 of yacc.c */ #line 295 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.enteringCode[lexerEnv] = QString((yyvsp[(2) - (2)].str)); } break; case 44: /* Line 1806 of yacc.c */ #line 299 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.leavingCode[lexerEnv] = QString((yyvsp[(2) - (2)].str)); } break; case 47: /* Line 1806 of yacc.c */ #line 306 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { r = "\nlxRETURN(" + QString((yyvsp[(1) - (1)].str)) + ")\n"; } break; case 48: /* Line 1806 of yacc.c */ #line 309 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { r = "\nlxCONTINUE;\n"; } break; case 49: /* Line 1806 of yacc.c */ #line 312 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { r = "\nlxSKIP\n"; } break; case 50: /* Line 1806 of yacc.c */ #line 316 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) |= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 51: /* Line 1806 of yacc.c */ #line 317 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 52: /* Line 1806 of yacc.c */ #line 321 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) &= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 53: /* Line 1806 of yacc.c */ #line 322 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 54: /* Line 1806 of yacc.c */ #line 326 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) ^= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 55: /* Line 1806 of yacc.c */ #line 327 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 56: /* Line 1806 of yacc.c */ #line 331 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA((yyvsp[(2) - (2)].nfa)->negate()); delete (yyvsp[(2) - (2)].nfa); } break; case 57: /* Line 1806 of yacc.c */ #line 332 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(2) - (2)].nfa) |= KDevPG::GNFA::emptyWord()); delete (yyvsp[(2) - (2)].nfa); } break; case 58: /* Line 1806 of yacc.c */ #line 333 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 59: /* Line 1806 of yacc.c */ #line 337 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (2)].nfa) <<= *(yyvsp[(2) - (2)].nfa)); delete (yyvsp[(1) - (2)].nfa); delete (yyvsp[(2) - (2)].nfa); } break; case 60: /* Line 1806 of yacc.c */ #line 338 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 61: /* Line 1806 of yacc.c */ #line 342 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa)); KDevPG::GNFA *tmp = new KDevPG::GNFA(*(yyvsp[(3) - (3)].nfa) <<= *(yyvsp[(1) - (3)].nfa)); **tmp; *(yyval.nfa) <<= *tmp; delete tmp; delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 62: /* Line 1806 of yacc.c */ #line 343 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 63: /* Line 1806 of yacc.c */ #line 347 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(**(yyvsp[(1) - (2)].nfa)); delete (yyvsp[(1) - (2)].nfa); } break; case 64: /* Line 1806 of yacc.c */ #line 348 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (2)].nfa)); **(yyval.nfa); *(yyval.nfa) <<= *(yyvsp[(1) - (2)].nfa); delete (yyvsp[(1) - (2)].nfa); } break; case 65: /* Line 1806 of yacc.c */ #line 349 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 66: /* Line 1806 of yacc.c */ #line 353 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(2) - (3)].nfa)); delete (yyvsp[(2) - (3)].nfa); } break; case 67: /* Line 1806 of yacc.c */ #line 354 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(2) - (3)].nfa); } break; case 68: /* Line 1806 of yacc.c */ #line 355 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } break; case 69: /* Line 1806 of yacc.c */ #line 356 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray((yyvsp[(1) - (1)].str))))); } break; case 70: /* Line 1806 of yacc.c */ #line 357 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray((yyvsp[(1) - (1)].str))))); } break; case 71: /* Line 1806 of yacc.c */ #line 358 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(!KDevPG::globalSystem.regexpById.contains((yyvsp[(1) - (1)].str))) { KDevPG::checkOut << "** ERROR: no named regexp " << (yyvsp[(1) - (1)].str) << endl; exit(-1); } KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[(yyvsp[(1) - (1)].str)]; if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) { KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); } (yyval.nfa) = new KDevPG::GNFA(*regexp); } break; case 72: /* Line 1806 of yacc.c */ #line 373 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } break; case 73: /* Line 1806 of yacc.c */ #line 377 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) |= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 74: /* Line 1806 of yacc.c */ #line 378 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 75: /* Line 1806 of yacc.c */ #line 382 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) &= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 76: /* Line 1806 of yacc.c */ #line 383 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 77: /* Line 1806 of yacc.c */ #line 387 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa) ^= *(yyvsp[(3) - (3)].nfa)); delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 78: /* Line 1806 of yacc.c */ #line 388 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 79: /* Line 1806 of yacc.c */ #line 392 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA((yyvsp[(2) - (2)].nfa)->negate()); delete (yyvsp[(2) - (2)].nfa); } break; case 80: /* Line 1806 of yacc.c */ #line 393 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(2) - (2)].nfa) |= KDevPG::GNFA::emptyWord()); delete (yyvsp[(2) - (2)].nfa); } break; case 81: /* Line 1806 of yacc.c */ #line 394 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 82: /* Line 1806 of yacc.c */ #line 398 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (2)].nfa) |= *(yyvsp[(2) - (2)].nfa)); delete (yyvsp[(1) - (2)].nfa); delete (yyvsp[(2) - (2)].nfa); } break; case 84: /* Line 1806 of yacc.c */ #line 403 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (3)].nfa)); KDevPG::GNFA *tmp = new KDevPG::GNFA(*(yyvsp[(3) - (3)].nfa) <<= *(yyvsp[(1) - (3)].nfa)); **tmp; *(yyval.nfa) <<= *tmp; delete tmp; delete (yyvsp[(1) - (3)].nfa); delete (yyvsp[(3) - (3)].nfa); } break; case 85: /* Line 1806 of yacc.c */ #line 404 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 86: /* Line 1806 of yacc.c */ #line 408 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(**(yyvsp[(1) - (2)].nfa)); delete (yyvsp[(1) - (2)].nfa); } break; case 87: /* Line 1806 of yacc.c */ #line 409 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(1) - (2)].nfa)); **(yyval.nfa); *(yyval.nfa) <<= *(yyvsp[(1) - (2)].nfa); delete (yyvsp[(1) - (2)].nfa); } break; case 88: /* Line 1806 of yacc.c */ #line 410 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(1) - (1)].nfa); } break; case 89: /* Line 1806 of yacc.c */ #line 414 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(*(yyvsp[(2) - (3)].nfa)); delete (yyvsp[(2) - (3)].nfa); } break; case 90: /* Line 1806 of yacc.c */ #line 415 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = (yyvsp[(2) - (3)].nfa); } break; case 91: /* Line 1806 of yacc.c */ #line 416 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } break; case 92: /* Line 1806 of yacc.c */ #line 417 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray((yyvsp[(1) - (1)].str))))); } break; case 93: /* Line 1806 of yacc.c */ #line 418 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { quint32 begin, end; QString str = KDevPG::unescaped(QByteArray((yyvsp[(1) - (1)].str))); assert(str.size() >= 3 && str.size() <= 5); if(str[1] == '-') { begin = str[0].unicode(); if(str.size() == 3) end = str[2].unicode(); else end = QChar::surrogateToUcs4(str[2], str[3]); } else { begin = QChar::surrogateToUcs4(str[0], str[1]); assert(str[2] == '-'); if(str.size() == 4) end = str[3].unicode(); else end = QChar::surrogateToUcs4(str[3], str[4]); } (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::range(begin, end+1)); } break; case 94: /* Line 1806 of yacc.c */ #line 441 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::collection(KDevPG::unescaped(QByteArray((yyvsp[(1) - (1)].str))))); } break; case 95: /* Line 1806 of yacc.c */ #line 442 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(!KDevPG::globalSystem.regexpById.contains((yyvsp[(1) - (1)].str))) { KDevPG::checkOut << "** ERROR: no named regexp " << (yyvsp[(1) - (1)].str) << endl; exit(-1); } KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[(yyvsp[(1) - (1)].str)]; if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) { KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); } (yyval.nfa) = new KDevPG::GNFA(*regexp); } break; case 96: /* Line 1806 of yacc.c */ #line 457 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.nfa) = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } break; case 97: /* Line 1806 of yacc.c */ #line 463 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::member(KDevPG::Settings::MemberItem::PublicDeclaration, (yyvsp[(5) - (5)].str)); } break; case 98: /* Line 1806 of yacc.c */ #line 465 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::member(KDevPG::Settings::MemberItem::ProtectedDeclaration, (yyvsp[(5) - (5)].str)); } break; case 99: /* Line 1806 of yacc.c */ #line 467 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::member(KDevPG::Settings::MemberItem::PrivateDeclaration, (yyvsp[(5) - (5)].str)); } break; case 100: /* Line 1806 of yacc.c */ #line 469 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::member(KDevPG::Settings::MemberItem::ConstructorCode, (yyvsp[(4) - (4)].str)); } break; case 101: /* Line 1806 of yacc.c */ #line 471 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::member(KDevPG::Settings::MemberItem::DestructorCode, (yyvsp[(4) - (4)].str)); } break; case 102: /* Line 1806 of yacc.c */ #line 475 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushTerminal((yyvsp[(1) - (1)].str),(yyvsp[(1) - (1)].str)); } break; case 103: /* Line 1806 of yacc.c */ #line 476 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushTerminal((yyvsp[(1) - (4)].str),(yyvsp[(3) - (4)].str)); } break; case 104: /* Line 1806 of yacc.c */ #line 477 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushTerminal((yyvsp[(3) - (3)].str),(yyvsp[(3) - (3)].str)); } break; case 105: /* Line 1806 of yacc.c */ #line 479 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushTerminal((yyvsp[(3) - (6)].str),(yyvsp[(5) - (6)].str)); } break; case 107: /* Line 1806 of yacc.c */ #line 484 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.pushRule((yyvsp[(2) - (3)].item)); } break; case 108: /* Line 1806 of yacc.c */ #line 488 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::globalSystem.zero(); } break; case 109: /* Line 1806 of yacc.c */ #line 489 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(2) - (3)].item); } break; case 110: /* Line 1806 of yacc.c */ #line 490 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 111: /* Line 1806 of yacc.c */ #line 491 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 112: /* Line 1806 of yacc.c */ #line 492 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::inlinedNonTerminal(KDevPG::globalSystem.pushSymbol((yyvsp[(2) - (2)].str))); } break; case 113: /* Line 1806 of yacc.c */ #line 493 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::annotation((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].item), false, (yyvsp[(2) - (3)].storageType)); } break; case 114: /* Line 1806 of yacc.c */ #line 494 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::annotation((yyvsp[(2) - (4)].str), (yyvsp[(4) - (4)].item), true, (yyvsp[(3) - (4)].storageType)); } break; case 115: /* Line 1806 of yacc.c */ #line 498 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::nonTerminal(KDevPG::globalSystem.pushSymbol((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].str)); } break; case 116: /* Line 1806 of yacc.c */ #line 499 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::globalSystem.terminal((yyvsp[(1) - (1)].str)); } break; case 117: /* Line 1806 of yacc.c */ #line 504 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.needStateManagement = true; (yyval.item) = KDevPG::tryCatch((yyvsp[(3) - (4)].item), 0); } break; case 118: /* Line 1806 of yacc.c */ #line 509 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.needStateManagement = true; (yyval.item) = KDevPG::tryCatch((yyvsp[(3) - (8)].item), (yyvsp[(7) - (8)].item)); } break; case 119: /* Line 1806 of yacc.c */ #line 515 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = const_cast(""); } break; case 120: /* Line 1806 of yacc.c */ #line 516 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 121: /* Line 1806 of yacc.c */ #line 520 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 122: /* Line 1806 of yacc.c */ #line 530 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.storageType) = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } break; case 123: /* Line 1806 of yacc.c */ #line 531 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.storageType) = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } break; case 124: /* Line 1806 of yacc.c */ #line 535 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::plus((yyvsp[(1) - (2)].item)); } break; case 125: /* Line 1806 of yacc.c */ #line 536 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::star((yyvsp[(1) - (2)].item)); } break; case 126: /* Line 1806 of yacc.c */ #line 537 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 127: /* Line 1806 of yacc.c */ #line 538 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::alternative((yyvsp[(2) - (2)].item), KDevPG::globalSystem.zero()); } break; case 128: /* Line 1806 of yacc.c */ #line 542 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 129: /* Line 1806 of yacc.c */ #line 544 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::CloneTree cl; (yyval.item) = KDevPG::cons((yyvsp[(1) - (3)].item), KDevPG::star(KDevPG::cons(cl.clone((yyvsp[(3) - (3)].item)), cl.clone((yyvsp[(1) - (3)].item))))); } break; case 130: /* Line 1806 of yacc.c */ #line 548 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::action((yyvsp[(1) - (2)].item), (yyvsp[(2) - (2)].str)); } break; case 131: /* Line 1806 of yacc.c */ #line 549 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::action(0, (yyvsp[(1) - (1)].str)); } break; case 132: /* Line 1806 of yacc.c */ #line 553 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 133: /* Line 1806 of yacc.c */ #line 554 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::cons((yyvsp[(1) - (2)].item), (yyvsp[(2) - (2)].item)); } break; case 134: /* Line 1806 of yacc.c */ #line 558 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 135: /* Line 1806 of yacc.c */ #line 559 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::condition((yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].item)); } break; case 136: /* Line 1806 of yacc.c */ #line 563 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 137: /* Line 1806 of yacc.c */ #line 564 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::alternative((yyvsp[(1) - (3)].item), (yyvsp[(3) - (3)].item)); } break; case 138: /* Line 1806 of yacc.c */ #line 569 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::evolve((yyvsp[(1) - (7)].item), KDevPG::globalSystem.pushSymbol((yyvsp[(3) - (7)].str)), (KDevPG::Model::VariableDeclarationItem*) (yyvsp[(6) - (7)].item), (yyvsp[(4) - (7)].str)); } break; case 139: /* Line 1806 of yacc.c */ #line 574 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::evolve((yyvsp[(1) - (7)].item), KDevPG::globalSystem.pushSymbol((yyvsp[(3) - (7)].str)), (KDevPG::Model::VariableDeclarationItem*) (yyvsp[(5) - (7)].item), (yyvsp[(7) - (7)].str)); } break; case 140: /* Line 1806 of yacc.c */ #line 579 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::evolve((yyvsp[(1) - (4)].item), KDevPG::globalSystem.pushSymbol((yyvsp[(3) - (4)].str)), 0, (yyvsp[(4) - (4)].str)); } break; case 141: /* Line 1806 of yacc.c */ #line 580 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { if(KDevPG::globalSystem.generateAst == false) { qFatal("Operator-expression-parsing is not yet supported with --no-ast!"); exit(-1); } operatorNode = KDevPG::createNode(); } break; case 142: /* Line 1806 of yacc.c */ #line 586 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::globalSystem.needOperatorStack = true; (yyval.item) = (yyvsp[(2) - (2)].item); } break; case 143: /* Line 1806 of yacc.c */ #line 590 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = const_cast(""); } break; case 144: /* Line 1806 of yacc.c */ #line 591 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 146: /* Line 1806 of yacc.c */ #line 597 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { ; } break; case 147: /* Line 1806 of yacc.c */ #line 602 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)(yyvsp[(2) - (9)].item); operatorNode->mName = (yyvsp[(5) - (9)].str); if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; (yyval.item) = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol((yyvsp[(5) - (9)].str)), (KDevPG::Model::VariableDeclarationItem*)(yyvsp[(7) - (9)].item), (yyvsp[(9) - (9)].str)); } break; case 148: /* Line 1806 of yacc.c */ #line 610 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)(yyvsp[(2) - (9)].item); operatorNode->mName = (yyvsp[(5) - (9)].str); if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; (yyval.item) = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol((yyvsp[(5) - (9)].str)), (KDevPG::Model::VariableDeclarationItem*)(yyvsp[(8) - (9)].item), (yyvsp[(6) - (9)].str)); } break; case 149: /* Line 1806 of yacc.c */ #line 618 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)(yyvsp[(2) - (6)].item); operatorNode->mName = (yyvsp[(5) - (6)].str); if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; (yyval.item) = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol((yyvsp[(5) - (6)].str)), 0, (yyvsp[(6) - (6)].str)); } break; case 150: /* Line 1806 of yacc.c */ #line 628 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushBin(*(yyvsp[(2) - (4)].operatorInformation), (yyvsp[(4) - (4)].str), (yyvsp[(3) - (4)].str)); free((yyvsp[(2) - (4)].operatorInformation)); } break; case 151: /* Line 1806 of yacc.c */ #line 629 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushTern(*(yyvsp[(2) - (5)].operatorInformation), *(yyvsp[(3) - (5)].operatorInformation), (yyvsp[(5) - (5)].str), (yyvsp[(4) - (5)].str)); free((yyvsp[(2) - (5)].operatorInformation)); free((yyvsp[(3) - (5)].operatorInformation)); } break; case 152: /* Line 1806 of yacc.c */ #line 630 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushPre(*(yyvsp[(2) - (3)].operatorInformation), (yyvsp[(3) - (3)].str)); free((yyvsp[(2) - (3)].operatorInformation)); } break; case 153: /* Line 1806 of yacc.c */ #line 631 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushPost(*(yyvsp[(2) - (3)].operatorInformation), "0", (yyvsp[(3) - (3)].str)); free((yyvsp[(2) - (3)].operatorInformation)); free((yyvsp[(3) - (3)].str)); } break; case 154: /* Line 1806 of yacc.c */ #line 632 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushPost(*(yyvsp[(2) - (4)].operatorInformation), (yyvsp[(4) - (4)].str), (yyvsp[(3) - (4)].str)); free((yyvsp[(2) - (4)].operatorInformation)); } break; case 155: /* Line 1806 of yacc.c */ #line 633 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { operatorNode->pushParen(*(yyvsp[(2) - (3)].operatorInformation), *(yyvsp[(3) - (3)].operatorInformation)); free((yyvsp[(2) - (3)].operatorInformation)); free((yyvsp[(3) - (3)].operatorInformation)); } break; case 156: /* Line 1806 of yacc.c */ #line 637 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (char*)"0"; } break; case 157: /* Line 1806 of yacc.c */ #line 638 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 158: /* Line 1806 of yacc.c */ #line 639 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (yyvsp[(2) - (2)].str); } break; case 159: /* Line 1806 of yacc.c */ #line 643 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (char*)"1"; } break; case 160: /* Line 1806 of yacc.c */ #line 644 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.str) = (char*)"0"; } break; case 161: /* Line 1806 of yacc.c */ #line 645 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { uint yyleng = strlen((yyvsp[(2) - (2)].str)); char *tmp = (char*)calloc(yyleng+7, sizeof(char)); tmp[0] = '('; strcpy(tmp+1, (yyvsp[(2) - (2)].str)); strcpy(tmp+yyleng+6-6+1, "?1:0)"); (yyval.str) = tmp; } break; case 162: /* Line 1806 of yacc.c */ #line 652 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { uint yyleng = strlen((yyvsp[(2) - (2)].str)); char *tmp = (char*)calloc(yyleng+7, sizeof(char)); tmp[0] = '('; strcpy(tmp+1, (yyvsp[(2) - (2)].str)); strcpy(tmp+yyleng+6-6+1, "?0:1)"); (yyval.str) = tmp; } break; case 163: /* Line 1806 of yacc.c */ #line 662 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.operatorInformation) = KDevPG::makeOperator(KDevPG::globalSystem.terminal((yyvsp[(3) - (4)].str)), (yyvsp[(2) - (4)].str), (yyvsp[(4) - (4)].str)); } break; case 164: /* Line 1806 of yacc.c */ #line 663 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.operatorInformation) = KDevPG::makeOperator(KDevPG::globalSystem.terminal((yyvsp[(3) - (3)].str)), (yyvsp[(2) - (3)].str), ""); } break; case 165: /* Line 1806 of yacc.c */ #line 664 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.operatorInformation) = KDevPG::makeOperator(KDevPG::globalSystem.terminal((yyvsp[(1) - (2)].str)), "", (yyvsp[(2) - (2)].str)); } break; case 166: /* Line 1806 of yacc.c */ #line 665 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.operatorInformation) = KDevPG::makeOperator(KDevPG::globalSystem.terminal((yyvsp[(1) - (1)].str)), "", ""); } break; case 167: /* Line 1806 of yacc.c */ #line 669 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = (yyvsp[(1) - (1)].item); } break; case 168: /* Line 1806 of yacc.c */ #line 671 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { KDevPG::Model::VariableDeclarationItem *last = (KDevPG::Model::VariableDeclarationItem*) (yyvsp[(1) - (2)].item); while (last->mNext != 0) { last = last->mNext; } last->mNext = (KDevPG::Model::VariableDeclarationItem*) (yyvsp[(2) - (2)].item); (yyval.item) = (yyvsp[(1) - (2)].item); } break; case 169: /* Line 1806 of yacc.c */ #line 683 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::variableDeclaration((yyvsp[(1) - (6)].declarationType), (yyvsp[(2) - (6)].storageType), (yyvsp[(3) - (6)].variableType), false, (yyvsp[(4) - (6)].str), (yyvsp[(6) - (6)].str)); } break; case 170: /* Line 1806 of yacc.c */ #line 685 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::variableDeclaration((yyvsp[(1) - (5)].declarationType), (yyvsp[(2) - (5)].storageType), KDevPG::Model::VariableDeclarationItem::TypeToken, false, (yyvsp[(4) - (5)].str), ""); } break; case 171: /* Line 1806 of yacc.c */ #line 687 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::variableDeclaration((yyvsp[(1) - (7)].declarationType), (yyvsp[(2) - (7)].storageType), (yyvsp[(3) - (7)].variableType), true, (yyvsp[(5) - (7)].str), (yyvsp[(7) - (7)].str)); } break; case 172: /* Line 1806 of yacc.c */ #line 689 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.item) = KDevPG::variableDeclaration((yyvsp[(1) - (6)].declarationType), (yyvsp[(2) - (6)].storageType), KDevPG::Model::VariableDeclarationItem::TypeToken, true, (yyvsp[(5) - (6)].str), ""); } break; case 173: /* Line 1806 of yacc.c */ #line 693 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.declarationType) = KDevPG::Model::VariableDeclarationItem::DeclarationLocal; } break; case 174: /* Line 1806 of yacc.c */ #line 694 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.declarationType) = KDevPG::Model::VariableDeclarationItem::DeclarationArgument; } break; case 175: /* Line 1806 of yacc.c */ #line 698 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.storageType) = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } break; case 176: /* Line 1806 of yacc.c */ #line 699 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.storageType) = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } break; case 177: /* Line 1806 of yacc.c */ #line 703 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.variableType) = KDevPG::Model::VariableDeclarationItem::TypeNode; } break; case 178: /* Line 1806 of yacc.c */ #line 704 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" { (yyval.variableType) = KDevPG::Model::VariableDeclarationItem::TypeVariable; } break; /* Line 1806 of yacc.c */ #line 3192 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-parser.cc" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } /* Line 2067 of yacc.c */ #line 707 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy" diff --git a/kdev-pg/kdev-pg-parser.yy b/kdev-pg/kdev-pg-parser.yy index 8f8d604..89ed1c0 100644 --- a/kdev-pg/kdev-pg-parser.yy +++ b/kdev-pg/kdev-pg-parser.yy @@ -1,707 +1,707 @@ %{ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg.h" #include "kdev-pg-clone-tree.h" #include "kdev-pg-regexp.h" #include "kdev-pg-unicode-loader.h" #include "kdev-pg-checker.h" -#include +#include #include extern int yylex(); extern void yyerror(const char* msg); extern int yyLine; QString lexerEnv; namespace KDevPG { extern QFile file; extern QTextStream checkOut; } KDevPG::Model::OperatorItem *operatorNode = 0; QString r; %} %union { KDevPG::Model::Node *item; char* str; KDevPG::Model::VariableDeclarationItem::DeclarationType declarationType; KDevPG::Model::VariableDeclarationItem::StorageType storageType; KDevPG::Model::VariableDeclarationItem::VariableType variableType; KDevPG::Model::Operator *operatorInformation; KDevPG::GNFA *nfa; } %token T_IDENTIFIER T_ARROW T_TERMINAL T_CODE T_STRING T_UNQUOTED_STRING T_NUMBER ';' %token T_TOKEN_DECLARATION T_TOKEN_STREAM_DECLARATION T_NAMESPACE_DECLARATION %token T_PARSERCLASS_DECLARATION T_LEXERCLASS_DECLARATION %token T_PUBLIC T_PRIVATE T_PROTECTED T_DECLARATION T_BITS %token T_CONSTRUCTOR T_DESTRUCTOR T_TRY_RECOVER T_TRY_ROLLBACK T_CATCH %token T_RULE_ARGUMENTS T_MEMBER T_TEMPORARY T_ARGUMENT T_EXPORT_MACRO %token T_NODE T_NODE_SEQUENCE T_TOKEN T_VARIABLE T_EXPORT_MACRO_HEADER %token T_AST_DECLARATION %token T_PARSER_DECLARATION_HEADER T_PARSER_BITS_HEADER T_AST_HEADER %token T_LEXER_DECLARATION_HEADER T_LEXER_BITS_HEADER %token T_PARSER_BASE T_AST_BASE T_LEXER_BASE %token T_BIN T_PRE T_POST T_TERN %token T_LOPR T_ROPR %token T_LEFT_ASSOC T_RIGHT_ASSOC T_IS_LEFT_ASSOC T_IS_RIGHT_ASSOC T_PRIORITY %token T_PAREN %token T_INLINE %token T_LEXER T_INPUT_STREAM T_INPUT_ENCODING T_TABLE_LEXER T_SEQUENCE_LEXER %token T_NAMED_REGEXP T_CONTINUE T_RANGE T_FAIL T_LOOKAHEAD T_BARRIER %token T_ENTER_RULE_SET T_LEAVE_RULE_SET %type T_IDENTIFIER T_TERMINAL T_CODE T_STRING T_UNQUOTED_STRING T_RULE_ARGUMENTS T_NUMBER T_NAMED_REGEXP T_RANGE %type name code_opt rule_arguments_opt priority assoc opt_lexer_action %type item primary_item try_item primary_atom unary_item %type postfix_item option_item item_sequence conditional_item %type member_declaration_rest variableDeclarations variableDeclaration operatorRule %type declarationType_opt %type scope storageType %type variableType /* %type operatorDeclaration operatorDeclarations operatorRule */ %type operator %type regexp regexp1 regexp2 regexp3 regexp4 regexp5 regexp6 regexp7 aregexp aregexp1 aregexp2 aregexp3 aregexp4 aregexp5 aregexp6 aregexp7 %% system : code_opt { KDevPG::globalSystem.decl = $1; } declarations rules code_opt { KDevPG::globalSystem.bits += $5; } ; declarations : declaration | declarations declaration ; declaration : T_PARSERCLASS_DECLARATION member_declaration_rest { KDevPG::globalSystem.pushParserClassMember($2); } | T_PARSERCLASS_DECLARATION '(' T_BITS ')' T_CODE { KDevPG::globalSystem.bits += $5; } | T_LEXERCLASS_DECLARATION member_declaration_rest { KDevPG::globalSystem.pushLexerClassMember($2); } | T_LEXERCLASS_DECLARATION '(' T_BITS ')' T_CODE { KDevPG::globalSystem.lexerBits += $5; } | T_TOKEN_DECLARATION declared_tokens ';' | T_TABLE_LEXER { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%table_lexer) before any lexer rules"; exit(-1); } switch(KDevPG::GDFA::type) { case KDevPG::SAscii: KDevPG::GDFA::type = KDevPG::TAscii; break; case KDevPG::SLatin1: KDevPG::GDFA::type = KDevPG::TLatin1; break; case KDevPG::SUtf8: KDevPG::GDFA::type = KDevPG::TUtf8; break; case KDevPG::SUcs2: KDevPG::GDFA::type = KDevPG::TUcs2; break; case KDevPG::SUtf16: KDevPG::GDFA::type = KDevPG::TUtf16; break; /* case KDevPG::SUcs4: KDevPG::GDFA::type = KDevPG::TUcs4; break; */ default: /* empty */; } } | T_SEQUENCE_LEXER { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } switch(KDevPG::GDFA::type) { case KDevPG::TAscii: KDevPG::GDFA::type = KDevPG::SAscii; break; case KDevPG::TLatin1: KDevPG::GDFA::type = KDevPG::SLatin1; break; case KDevPG::TUtf8: KDevPG::GDFA::type = KDevPG::SUtf8; break; case KDevPG::TUcs2: KDevPG::GDFA::type = KDevPG::SUcs2; break; case KDevPG::TUtf16: KDevPG::GDFA::type = KDevPG::SUtf16; break; /* case KDevPG::TUcs4: KDevPG::GDFA::type = KDevPG::SUcs4; break; */ default: /* empty */; } } | T_INPUT_ENCODING T_STRING { if(KDevPG::globalSystem.hasLexer) { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } int base = (KDevPG::GDFA::type / 4) * 4; // warning: magic constant: number of different codecs QString str = $2; str = str.toLower(); str.replace('-', ""); if(str == "ascii") /* base += 0*/; else if(str == "latin1") base += 1; else if(str == "utf8") base += 2; else if(str == "ucs2") base += 3; else if(str == "utf16") base += 4; else if(str == "ucs4" || str == "utf32") base += 5; else { KDevPG::checkOut << "** ERROR unknown codec ``" << $2 << "''" << endl; exit(-1); } KDevPG::GDFA::type = KDevPG::AutomatonType(base); } | T_TOKEN_STREAM_DECLARATION T_IDENTIFIER ';' { KDevPG::globalSystem.tokenStream = $2; } | T_EXPORT_MACRO T_STRING { KDevPG::globalSystem.exportMacro = $2; } | T_EXPORT_MACRO_HEADER T_STRING { KDevPG::globalSystem.exportMacroHeader = $2; } | T_NAMESPACE_DECLARATION T_CODE { KDevPG::globalSystem.namespaceCode = $2; } | T_AST_DECLARATION T_CODE { KDevPG::globalSystem.astCode = $2; } | T_PARSER_DECLARATION_HEADER T_STRING { KDevPG::globalSystem.pushParserDeclarationHeader($2); } | T_PARSER_BITS_HEADER T_STRING { KDevPG::globalSystem.pushParserBitsHeader($2); } | T_AST_HEADER T_STRING { KDevPG::globalSystem.pushAstHeader($2); } | T_LEXER_DECLARATION_HEADER T_STRING { KDevPG::globalSystem.pushLexerDeclarationHeader($2); } | T_INPUT_STREAM T_STRING { KDevPG::globalSystem.inputStream = $2; } | T_LEXER_BITS_HEADER T_STRING { KDevPG::globalSystem.pushLexerBitsHeader($2); } | T_AST_BASE T_IDENTIFIER T_STRING { KDevPG::globalSystem.astBaseClasses[$2] = $3; } | T_PARSER_BASE T_STRING { KDevPG::globalSystem.parserBaseClass = $2; } | T_LEXER_BASE T_STRING { KDevPG::globalSystem.lexerBaseClass = $2; } | T_LEXER T_STRING { KDevPG::globalSystem.hasLexer = true; lexerEnv = $2; if(KDevPG::globalSystem.lexerActions[lexerEnv].empty()) KDevPG::globalSystem.lexerActions[lexerEnv].push_back("qDebug() << \"error\"; exit(-1);"); } T_ARROW lexer_declaration_rest ';' | T_LEXER { KDevPG::globalSystem.hasLexer = true; KDevPG::loadUnicodeData(); lexerEnv = "start"; if(KDevPG::globalSystem.lexerActions["start"].empty()) KDevPG::globalSystem.lexerActions["start"].push_back("qDebug() << \"error\"; exit(-1);"); } T_ARROW lexer_declaration_rest ';' ; lexer_declaration_rest : regexp T_ARROW T_IDENTIFIER ';' { KDevPG::globalSystem.regexpById[$3] = $1; } lexer_declaration_rest | regexp code_opt opt_lexer_action ';' { if($1->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if($1->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; QString s = QString($2) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } lexer_declaration_rest | regexp T_LOOKAHEAD '(' regexp ')' code_opt opt_lexer_action ';' { if($1->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if($1->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; bool ignore = false; auto minLen = $4->minLength(), maxLen = $4->maxLength(); if(minLen == 0) { KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-lookahead at line " << yyLine << ", ignore the lookahead." << endl; ignore = true; } else if(minLen != maxLen) { KDevPG::checkOut << "** WARNING Invalid lookahead (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the lookahead." << endl; ignore = true; } if(ignore) { QString s = QString($6) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } else { QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString($6) + QString(r); *$1 <<= *$4; KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } } lexer_declaration_rest | regexp T_BARRIER '(' regexp ')' code_opt opt_lexer_action ';' { if($1->acceptsEpsilon()) KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << endl; else if($1->isEmpty()) KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << endl; bool ignore = false; auto minLen = $4->minLength(), maxLen = $4->maxLength(); if(minLen == 0) { KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-barrier at line " << yyLine << ", ignore the barrier." << endl; ignore = true; } else if(minLen != maxLen) { KDevPG::checkOut << "** WARNING Invalid barrier (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the barrier." << endl; ignore = true; } if(ignore) { QString s = QString($6) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } else { KDevPG::GNFA exclude = KDevPG::GNFA::anything(); exclude <<= *$4; exclude <<= KDevPG::GNFA::anything(); KDevPG::GNFA *staying = new KDevPG::GNFA(*$1); *staying ^= exclude; KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back(staying); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(QString($6) + QString(r)); // barrier should not get read partially exclude <<= KDevPG::GNFA::anyChar(); *$1 <<= *$4; *$1 ^= exclude; QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString($6) + QString(r); KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); } } lexer_declaration_rest | T_FAIL T_CODE { KDevPG::globalSystem.lexerActions[lexerEnv][0] = QString($2); } lexer_declaration_rest | T_ENTER_RULE_SET T_CODE { KDevPG::globalSystem.enteringCode[lexerEnv] = QString($2); } lexer_declaration_rest | T_LEAVE_RULE_SET T_CODE { KDevPG::globalSystem.leavingCode[lexerEnv] = QString($2); } lexer_declaration_rest | /* empty */ ; opt_lexer_action : T_TERMINAL { r = "\nlxRETURN(" + QString($1) + ")\n"; } | T_CONTINUE { r = "\nlxCONTINUE;\n"; } | /* empty */ { r = "\nlxSKIP\n"; } ; regexp : regexp '|' regexp1 { $$ = new KDevPG::GNFA(*$1 |= *$3); delete $1; delete $3; } | regexp1 { $$ = $1; } ; regexp1 : regexp1 '&' regexp2 { $$ = new KDevPG::GNFA(*$1 &= *$3); delete $1; delete $3; } | regexp2 { $$ = $1; } ; regexp2 : regexp3 '^' regexp2 { $$ = new KDevPG::GNFA(*$1 ^= *$3); delete $1; delete $3; } | regexp3 { $$ = $1; } ; regexp3 : '~' regexp3 { $$ = new KDevPG::GNFA($2->negate()); delete $2; } | '?' regexp3 { $$ = new KDevPG::GNFA(*$2 |= KDevPG::GNFA::emptyWord()); delete $2; } | regexp4 { $$ = $1; } ; regexp4 : regexp4 regexp5 { $$ = new KDevPG::GNFA(*$1 <<= *$2); delete $1; delete $2; } | regexp5 { $$ = $1; } ; regexp5 : regexp5 '@' regexp6 { $$ = new KDevPG::GNFA(*$1); KDevPG::GNFA *tmp = new KDevPG::GNFA(*$3 <<= *$1); **tmp; *$$ <<= *tmp; delete tmp; delete $1; delete $3; } | regexp6 { $$ = $1; } ; regexp6 : regexp6 '*' { $$ = new KDevPG::GNFA(**$1); delete $1; } | regexp6 '+' { $$ = new KDevPG::GNFA(*$1); **$$; *$$ <<= *$1; delete $1; } | regexp7 { $$ = $1; } ; regexp7 : '(' regexp ')' { $$ = new KDevPG::GNFA(*$2); delete $2; } | '[' aregexp ']' { $$ = $2; } | '.' { $$ = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } | T_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } | T_UNQUOTED_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } | T_NAMED_REGEXP { if(!KDevPG::globalSystem.regexpById.contains($1)) { KDevPG::checkOut << "** ERROR: no named regexp " << $1 << endl; exit(-1); } KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[$1]; if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) { KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); } $$ = new KDevPG::GNFA(*regexp); } | /* empty */ { $$ = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } ; aregexp : aregexp '|' aregexp1 { $$ = new KDevPG::GNFA(*$1 |= *$3); delete $1; delete $3; } | aregexp1 { $$ = $1; } ; aregexp1 : aregexp1 '&' aregexp2 { $$ = new KDevPG::GNFA(*$1 &= *$3); delete $1; delete $3; } | aregexp2 { $$ = $1; } ; aregexp2 : aregexp3 '^' aregexp2 { $$ = new KDevPG::GNFA(*$1 ^= *$3); delete $1; delete $3; } | aregexp3 { $$ = $1; } ; aregexp3 : '~' aregexp3 { $$ = new KDevPG::GNFA($2->negate()); delete $2; } | '?' aregexp3 { $$ = new KDevPG::GNFA(*$2 |= KDevPG::GNFA::emptyWord()); delete $2; } | aregexp4 { $$ = $1; } ; aregexp4 : aregexp4 aregexp5 { $$ = new KDevPG::GNFA(*$1 |= *$2); delete $1; delete $2; } | aregexp5 ; aregexp5 : aregexp5 '@' aregexp6 { $$ = new KDevPG::GNFA(*$1); KDevPG::GNFA *tmp = new KDevPG::GNFA(*$3 <<= *$1); **tmp; *$$ <<= *tmp; delete tmp; delete $1; delete $3; } | aregexp6 { $$ = $1; } ; aregexp6 : aregexp6 '*' { $$ = new KDevPG::GNFA(**$1); delete $1; } | aregexp6 '+' { $$ = new KDevPG::GNFA(*$1); **$$; *$$ <<= *$1; delete $1; } | aregexp7 { $$ = $1; } ; aregexp7 : '(' regexp ')' { $$ = new KDevPG::GNFA(*$2); delete $2; } | '[' aregexp ']' { $$ = $2; } | '.' { $$ = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } | T_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } | T_RANGE { quint32 begin, end; QString str = KDevPG::unescaped(QByteArray($1)); assert(str.size() >= 3 && str.size() <= 5); if(str[1] == '-') { begin = str[0].unicode(); if(str.size() == 3) end = str[2].unicode(); else end = QChar::surrogateToUcs4(str[2], str[3]); } else { begin = QChar::surrogateToUcs4(str[0], str[1]); assert(str[2] == '-'); if(str.size() == 4) end = str[3].unicode(); else end = QChar::surrogateToUcs4(str[3], str[4]); } $$ = new KDevPG::GNFA(KDevPG::GNFA::range(begin, end+1)); } | T_UNQUOTED_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::collection(KDevPG::unescaped(QByteArray($1)))); } | T_NAMED_REGEXP { if(!KDevPG::globalSystem.regexpById.contains($1)) { KDevPG::checkOut << "** ERROR: no named regexp " << $1 << endl; exit(-1); } KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[$1]; if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) { KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); } $$ = new KDevPG::GNFA(*regexp); } | /* empty */ { $$ = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } ; member_declaration_rest : '(' T_PUBLIC T_DECLARATION ')' T_CODE { $$ = KDevPG::member(KDevPG::Settings::MemberItem::PublicDeclaration, $5); } | '(' T_PROTECTED T_DECLARATION ')' T_CODE { $$ = KDevPG::member(KDevPG::Settings::MemberItem::ProtectedDeclaration, $5); } | '(' T_PRIVATE T_DECLARATION ')' T_CODE { $$ = KDevPG::member(KDevPG::Settings::MemberItem::PrivateDeclaration, $5); } | '(' T_CONSTRUCTOR ')' T_CODE { $$ = KDevPG::member(KDevPG::Settings::MemberItem::ConstructorCode, $4); } | '(' T_DESTRUCTOR ')' T_CODE { $$ = KDevPG::member(KDevPG::Settings::MemberItem::DestructorCode, $4); } ; declared_tokens : T_TERMINAL { KDevPG::globalSystem.pushTerminal($1,$1); } | T_TERMINAL '(' T_STRING ')' { KDevPG::globalSystem.pushTerminal($1,$3); } | declared_tokens ',' T_TERMINAL { KDevPG::globalSystem.pushTerminal($3,$3); } | declared_tokens ',' T_TERMINAL '(' T_STRING ')' { KDevPG::globalSystem.pushTerminal($3,$5); } ; rules : /* empty */ | rules item ';' { KDevPG::globalSystem.pushRule($2); } ; primary_item : '0' { $$ = KDevPG::globalSystem.zero(); } | '(' option_item ')' { $$ = $2; } | try_item { $$ = $1; } | primary_atom { $$ = $1; } | T_INLINE T_IDENTIFIER { $$ = KDevPG::inlinedNonTerminal(KDevPG::globalSystem.pushSymbol($2)); } | name scope primary_atom { $$ = KDevPG::annotation($1, $3, false, $2); } | '#' name scope primary_atom { $$ = KDevPG::annotation($2, $4, true, $3); } ; primary_atom : T_IDENTIFIER rule_arguments_opt { $$ = KDevPG::nonTerminal(KDevPG::globalSystem.pushSymbol($1), $2); } | T_TERMINAL { $$ = KDevPG::globalSystem.terminal($1); } ; try_item : T_TRY_RECOVER '(' option_item ')' { KDevPG::globalSystem.needStateManagement = true; $$ = KDevPG::tryCatch($3, 0); } | T_TRY_ROLLBACK '(' option_item ')' T_CATCH '(' option_item ')' { KDevPG::globalSystem.needStateManagement = true; $$ = KDevPG::tryCatch($3, $7); } rule_arguments_opt : /* empty */ { $$ = const_cast(""); } | T_RULE_ARGUMENTS { $$ = $1; } ; name : T_IDENTIFIER { $$ = $1; } /* | T_IDENTIFIER '.' T_IDENTIFIER { $$ = $3; fprintf(stderr, "** WARNING support for scoped name" " ``%s.%s'' not implemented\n", $1, $3); }*/ ; scope : '=' { $$ = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } | ':' { $$ = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } ; unary_item : primary_item '+' { $$ = KDevPG::plus($1); } | primary_item '*' { $$ = KDevPG::star($1); } | primary_item { $$ = $1; } | '?' primary_item { $$ = KDevPG::alternative($2, KDevPG::globalSystem.zero()); } ; postfix_item : unary_item { $$ = $1; } | postfix_item '@' primary_item { KDevPG::CloneTree cl; $$ = KDevPG::cons($1, KDevPG::star(KDevPG::cons(cl.clone($3), cl.clone($1)))); } | postfix_item T_CODE { $$ = KDevPG::action($1, $2); } | T_CODE { $$ = KDevPG::action(0, $1); } ; item_sequence : postfix_item { $$ = $1; } | item_sequence postfix_item { $$ = KDevPG::cons($1, $2); } ; conditional_item : item_sequence { $$ = $1; } | '?' T_CODE item_sequence { $$ = KDevPG::condition($2, $3); } ; option_item : conditional_item { $$ = $1; } | option_item '|' conditional_item { $$ = KDevPG::alternative($1, $3); } ; item : option_item T_ARROW T_IDENTIFIER T_CODE '[' variableDeclarations ']' { $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), (KDevPG::Model::VariableDeclarationItem*) $6, $4); } | option_item T_ARROW T_IDENTIFIER '[' variableDeclarations ']' code_opt { $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), (KDevPG::Model::VariableDeclarationItem*) $5, $7); } | option_item T_ARROW T_IDENTIFIER code_opt { $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), 0, $4); } | { if(KDevPG::globalSystem.generateAst == false) { qFatal("Operator-expression-parsing is not yet supported with --no-ast!"); exit(-1); } operatorNode = KDevPG::createNode(); } operatorRule { KDevPG::globalSystem.needOperatorStack = true; $$ = $2; } ; code_opt : /* empty */ { $$ = const_cast(""); } | T_CODE { $$ = $1; } ; operatorDeclarations : operatorDeclaration operatorDeclarations | /* empty */ { ; } ; operatorRule : T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER '[' variableDeclarations ']' code_opt { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; operatorNode->mName = $5; if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), (KDevPG::Model::VariableDeclarationItem*)$7, $9); } | T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER T_CODE '[' variableDeclarations ']' { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; operatorNode->mName = $5; if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), (KDevPG::Model::VariableDeclarationItem*)$8, $6); } | T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER code_opt { operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; operatorNode->mName = $5; if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), 0, $6); } ; operatorDeclaration : T_BIN operator priority assoc { operatorNode->pushBin(*$2, $4, $3); free($2); } | T_TERN operator operator priority assoc { operatorNode->pushTern(*$2, *$3, $5, $4); free($2); free($3); } | T_PRE operator priority { operatorNode->pushPre(*$2, $3); free($2); } | T_POST operator priority { operatorNode->pushPost(*$2, "0", $3); free($2); free($3); } | T_POST operator priority assoc { operatorNode->pushPost(*$2, $4, $3); free($2); } | T_PAREN operator operator { operatorNode->pushParen(*$2, *$3); free($2); free($3); } ; priority : '0' { $$ = (char*)"0"; } | T_NUMBER { $$ = $1; } | T_PRIORITY T_CODE { $$ = $2; } ; assoc : T_LEFT_ASSOC { $$ = (char*)"1"; } | T_RIGHT_ASSOC { $$ = (char*)"0"; } | T_IS_LEFT_ASSOC T_CODE { uint yyleng = strlen($2); char *tmp = (char*)calloc(yyleng+7, sizeof(char)); tmp[0] = '('; strcpy(tmp+1, $2); strcpy(tmp+yyleng+6-6+1, "?1:0)"); $$ = tmp; } | T_IS_RIGHT_ASSOC T_CODE { uint yyleng = strlen($2); char *tmp = (char*)calloc(yyleng+7, sizeof(char)); tmp[0] = '('; strcpy(tmp+1, $2); strcpy(tmp+yyleng+6-6+1, "?0:1)"); $$ = tmp; } ; operator : '?' T_CODE T_TERMINAL T_CODE { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($3), $2, $4); } | '?' T_CODE T_TERMINAL { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($3), $2, ""); } | T_TERMINAL T_CODE { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($1), "", $2); } | T_TERMINAL { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($1), "", ""); } ; variableDeclarations : variableDeclaration { $$ = $1; } | variableDeclarations variableDeclaration { KDevPG::Model::VariableDeclarationItem *last = (KDevPG::Model::VariableDeclarationItem*) $1; while (last->mNext != 0) { last = last->mNext; } last->mNext = (KDevPG::Model::VariableDeclarationItem*) $2; $$ = $1; } ; variableDeclaration : declarationType_opt storageType variableType T_IDENTIFIER ':' T_IDENTIFIER { $$ = KDevPG::variableDeclaration($1, $2, $3, false, $4, $6); } | declarationType_opt storageType T_TOKEN T_IDENTIFIER ';' { $$ = KDevPG::variableDeclaration($1, $2, KDevPG::Model::VariableDeclarationItem::TypeToken, false, $4, ""); } | declarationType_opt storageType variableType '#' T_IDENTIFIER ':' T_IDENTIFIER { $$ = KDevPG::variableDeclaration($1, $2, $3, true, $5, $7); } | declarationType_opt storageType T_TOKEN '#' T_IDENTIFIER ';' { $$ = KDevPG::variableDeclaration($1, $2, KDevPG::Model::VariableDeclarationItem::TypeToken, true, $5, ""); } ; declarationType_opt : /* empty */ { $$ = KDevPG::Model::VariableDeclarationItem::DeclarationLocal; } | T_ARGUMENT { $$ = KDevPG::Model::VariableDeclarationItem::DeclarationArgument; } ; storageType : T_MEMBER { $$ = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } | T_TEMPORARY { $$ = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } ; variableType : T_NODE { $$ = KDevPG::Model::VariableDeclarationItem::TypeNode; } | T_VARIABLE { $$ = KDevPG::Model::VariableDeclarationItem::TypeVariable; } ; %% diff --git a/kdev-pg/kdev-pg-pretty-printer.cpp b/kdev-pg/kdev-pg-pretty-printer.cpp index e5fef2e..2582ac2 100644 --- a/kdev-pg/kdev-pg-pretty-printer.cpp +++ b/kdev-pg/kdev-pg-pretty-printer.cpp @@ -1,162 +1,162 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdev-pg-pretty-printer.h" -#include -#include +#include +#include #include #include namespace KDevPG { void PrettyPrinter::visitZero(Model::ZeroItem *node) { Q_UNUSED(node); out << "0"; } void PrettyPrinter::visitPlus(Model::PlusItem *node) { out << "("; visitNode(node->mItem); out << ")"; out << "+"; } void PrettyPrinter::visitStar(Model::StarItem *node) { out << "("; visitNode(node->mItem); out << ")"; out << "*"; } void PrettyPrinter::visitSymbol(Model::SymbolItem *node) { out << node->mName; } void PrettyPrinter::visitAction(Model::ActionItem *node) { visitNode(node->mItem); } void PrettyPrinter::visitAlternative(Model::AlternativeItem *node) { QList top_level_nodes; QStack working_list; working_list.push(node->mRight); working_list.push(node->mLeft); while (!working_list.empty()) { Model::Node *n = working_list.top(); working_list.pop(); if (Model::AlternativeItem *a = nodeCast(n)) { working_list.push(a->mRight); working_list.push(a->mLeft); } else { top_level_nodes.push_back(n); } } bool initial = true; out << "("; QList::iterator it = top_level_nodes.begin(); while (it != top_level_nodes.end()) { if (!initial) out << " | "; Model::Node *n = *it++; visitNode(n); initial = false; } out << ")"; } void PrettyPrinter::visitCons(Model::ConsItem *node) { visitNode(node->mLeft); out << " "; visitNode(node->mRight); } void PrettyPrinter::visitEvolve(Model::EvolveItem *node) { visitNode(node->mItem); out << " -> "; visitNode(node->mSymbol); } void PrettyPrinter::visitTryCatch(Model::TryCatchItem *node) { out << "try/" << (node->mCatchItem ? "rollback" : "recover") << "("; visitNode(node->mTryItem); out << ")"; if (node->mCatchItem) { out << " catch("; visitNode(node->mCatchItem); out << ")"; } } void PrettyPrinter::visitAlias(Model::AliasItem *node) { Q_UNUSED(node); assert(0); // ### not implemented yet } void PrettyPrinter::visitTerminal(Model::TerminalItem *node) { out << node->mName; } void PrettyPrinter::visitInlinedNonTerminal(Model::InlinedNonTerminalItem *node) { visitNode(node->mSymbol); } void PrettyPrinter::visitNonTerminal(Model::NonTerminalItem *node) { visitNode(node->mSymbol); } void PrettyPrinter::visitAnnotation(Model::AnnotationItem *node) { out << ((node->mDeclaration->mIsSequence) ? "#" : "") << node->mDeclaration->mName << ((node->mDeclaration->mStorageType == Model::VariableDeclarationItem::StorageTemporary) ? ":" : "="); visitNode(node->mItem); } } diff --git a/kdev-pg/kdev-pg-pretty-printer.h b/kdev-pg/kdev-pg-pretty-printer.h index f234c0f..839239a 100644 --- a/kdev-pg/kdev-pg-pretty-printer.h +++ b/kdev-pg/kdev-pg-pretty-printer.h @@ -1,63 +1,63 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_PRETTY_PRINTER_H #define KDEV_PG_PRETTY_PRINTER_H #include "kdev-pg-default-visitor.h" -#include +#include namespace KDevPG { class PrettyPrinter: protected DefaultVisitor { public: QTextStream& out; PrettyPrinter(QTextStream& o): out(o) {} void operator()(Model::Node *node) { visitNode(node); out.flush(); } protected: void visitZero(Model::ZeroItem *node) override; void visitPlus(Model::PlusItem *node) override; void visitStar(Model::StarItem *node) override; void visitSymbol(Model::SymbolItem *node) override; void visitAction(Model::ActionItem *node) override; void visitAlternative(Model::AlternativeItem *node) override; void visitCons(Model::ConsItem *node) override; void visitEvolve(Model::EvolveItem *node) override; void visitTryCatch(Model::TryCatchItem *node) override; void visitAlias(Model::AliasItem *node) override; void visitTerminal(Model::TerminalItem *node) override; void visitInlinedNonTerminal(Model::InlinedNonTerminalItem *node) override; void visitNonTerminal(Model::NonTerminalItem *node) override; void visitAnnotation(Model::AnnotationItem *node) override; }; } #endif // KDEV_PG_PRETTY_PRINTER_H diff --git a/kdev-pg/kdev-pg-serialize-visitor-gen.h b/kdev-pg/kdev-pg-serialize-visitor-gen.h index c965e7c..c00428b 100644 --- a/kdev-pg/kdev-pg-serialize-visitor-gen.h +++ b/kdev-pg/kdev-pg-serialize-visitor-gen.h @@ -1,68 +1,68 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2006 Adam Treat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_SERIALIZE_VISITORGEN_H #define KDEV_PG_SERIALIZE_VISITORGEN_H #include "kdev-pg-default-visitor.h" #include "kdev-pg-default-visitor-bits-gen.h" // for the HasMemberNodes class -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateSerializeVisitor { public: QTextStream& out; public: GenerateSerializeVisitor(QTextStream& o): out(o) {} void operator()(); }; class GenerateSerializeVisitorRule: protected DefaultVisitor { public: QTextStream& out; QSet mNames; QList mVariableDeclarations; public: GenerateSerializeVisitorRule(QTextStream& o): out(o) {} void operator()(QPair const &__it); protected: void visitVariableDeclaration(Model::VariableDeclarationItem *node) override; }; } #endif // KDEV_PG_SERIALIZE_VISITORGEN_H diff --git a/kdev-pg/kdev-pg-token-type-gen.h b/kdev-pg/kdev-pg-token-type-gen.h index 43af0e9..01560d2 100644 --- a/kdev-pg/kdev-pg-token-type-gen.h +++ b/kdev-pg/kdev-pg-token-type-gen.h @@ -1,42 +1,42 @@ /* This file is part of kdev-pg-qt Copyright (C) 2011 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPG_KDEV_PG_TOKEN_TYPE_GEN_H #define KDEVPG_KDEV_PG_TOKEN_TYPE_GEN_H -#include +#include namespace KDevPG { class GenerateTokenType { public: QTextStream& out; public: GenerateTokenType(QTextStream& o): out(o) {} void operator()(); }; } #endif // KDEVPG_KDEV_PG_TOKEN_TYPE_GEN_H diff --git a/kdev-pg/kdev-pg-visitor-bits-gen.h b/kdev-pg/kdev-pg-visitor-bits-gen.h index 1ef851d..fc527ee 100644 --- a/kdev-pg/kdev-pg-visitor-bits-gen.h +++ b/kdev-pg/kdev-pg-visitor-bits-gen.h @@ -1,48 +1,48 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_VISITOR_BITS_GEN_H #define KDEV_PG_VISITOR_BITS_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateVisitorBits { public: QTextStream& out; public: explicit GenerateVisitorBits(QTextStream& o): out(o) {} void operator()(); }; } #endif // KDEV_PG_VISITORGEN_H diff --git a/kdev-pg/kdev-pg-visitor-gen.h b/kdev-pg/kdev-pg-visitor-gen.h index b5f1506..deee65d 100644 --- a/kdev-pg/kdev-pg-visitor-gen.h +++ b/kdev-pg/kdev-pg-visitor-gen.h @@ -1,48 +1,48 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_VISITOR_GEN_H #define KDEV_PG_VISITOR_GEN_H #include "kdev-pg-default-visitor.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace KDevPG { class GenerateVisitor { public: QTextStream& out; public: explicit GenerateVisitor(QTextStream& o): out(o) {} void operator()(); }; } #endif // KDEV_PG_VISITOR_GEN_H diff --git a/kdev-pg/kdev-pg.h b/kdev-pg/kdev-pg.h index d6d4c0f..22622bd 100644 --- a/kdev-pg/kdev-pg.h +++ b/kdev-pg/kdev-pg.h @@ -1,350 +1,350 @@ /* This file is part of kdev-pg-qt Copyright (C) 2005 Roberto Raggi Copyright (C) 2006 Jakob Petsovits Copyright (C) 2006 Alexander Dymo This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEV_PG_H #define KDEV_PG_H #include "kdev-pg-ast.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include namespace KDevPG { class GNFA; class GDFA; void deleteNFA(GNFA*); void deleteDFA(GDFA*); Model::ZeroItem *zero(); Model::PlusItem *plus(Model::Node *item); Model::StarItem *star(Model::Node *item); Model::SymbolItem *symbol(const QString& name); Model::ActionItem *action(Model::Node *item, const QString& code); Model::AlternativeItem *alternative(Model::Node *left, Model::Node *right); Model::ConsItem *cons(Model::Node *left, Model::Node *right); Model::EvolveItem *evolve( Model::Node *item, Model::SymbolItem *symbol, Model::VariableDeclarationItem *declarations, const QString& code ); Model::TryCatchItem *tryCatch(Model::Node *try_item, Model::Node *catch_item); Model::AliasItem *alias(const QString& code, Model::SymbolItem *symbol); Model::TerminalItem *terminal(const QString& name, const QString& description); Model::NonTerminalItem *nonTerminal(Model::SymbolItem *symbol, const QString& arguments); Model::InlinedNonTerminalItem *inlinedNonTerminal(Model::SymbolItem *symbol); Model::ConditionItem *condition(const QString& code, Model::Node *item); Model::AnnotationItem *annotation( const QString& name, Model::Node *item, bool isSequence, Model::VariableDeclarationItem::StorageType storageType ); Model::VariableDeclarationItem *variableDeclaration( Model::VariableDeclarationItem::DeclarationType declarationType, Model::VariableDeclarationItem::StorageType storageType, Model::VariableDeclarationItem::VariableType variableType, bool isSequence, const QString& name, const QString& type ); bool isOperatorSymbol(Model::SymbolItem *node); Settings::MemberItem *member(Settings::MemberItem::MemberKind kind, const QString& code); Model::Operator *makeOperator(Model::Node *tok, const QString& cond, const QString& code); inline void capitalize(QString& str) { if(!str.isEmpty()) str.replace(0, 1, str.at(0).toUpper()); } inline QString capitalized(const QString& str) { QString ret(str); capitalize(ret); return ret; } QString unescaped(const QByteArray& str); class World { public: struct MemberCode { QList declarations; QList constructorCode; QList destructorCode; }; typedef QSet NodeSet; typedef QMap SymbolSet; typedef QMap TerminalSet; typedef QMultiMap Environment; typedef QMultiMap NamespaceSet; typedef QMap, NodeSet> FirstSet; typedef QMap, NodeSet> FollowSet; /**pair: list of rules whose FIRST set is used to calculate FOLLOW, list of rules whose FOLLOW set is used to calculate FOLLOW*/ typedef QPair FollowDep; /**key: rule whose FOLLOW set has a dependency on other rules' FIRST and FOLLOW, value: follow set dependency*/ typedef QMap FollowDeps; typedef QMap AstBaseClasses; World() : tokenStream("KDevPG::TokenStream"), language(), ns(), decl(), bits(), exportMacro(""), exportMacroHeader(), astCode(""), namespaceCode(""), inputStream("KDevPG::QUtf16ToUcs4Iterator"), generateAst(true), hasLexer(false), generateSerializeVisitor(false), generateDebugVisitor(false), generateTokenText(false), needStateManagement(false), needOperatorStack(false), lineNumberPolicy(FullLineNumbers), visitorTable(false), conflictHandling(Permissive), mZero(nullptr), lexerBaseClass("KDevPG::TokenStream") {} ~World() { for(auto i = regexpById.begin(); i != regexpById.end(); ++i) deleteNFA(*i); for(auto i = lexerEnvResults.begin(); i != lexerEnvResults.end(); ++i) deleteNFA(*i); for(auto i = dfaForNfa.begin(); i != dfaForNfa.end(); ++i) deleteDFA(*i); } // options QString tokenStream; QString language; QString ns; QString decl; QString bits; QString lexerBits; QString exportMacro; QString exportMacroHeader; QString astCode; QString namespaceCode; QStringList parserDeclarationHeaders; QStringList parserBitsHeaders; QStringList astHeaders; QStringList lexerDeclarationHeaders; QStringList lexerBitsHeaders; QString inputStream; bool generateAst: 1; bool hasLexer: 1; bool generateSerializeVisitor: 1; bool generateDebugVisitor: 1; bool generateTokenText: 1; bool needStateManagement: 1; bool needOperatorStack: 1; enum { BeautifulCode, CompatibilityLineNumbers, FullLineNumbers } lineNumberPolicy; bool beautifulCode: 1; bool visitorTable: 1; enum { Ignore = 0, Permissive = 1, Strict = 2 } conflictHandling: 2; Model::ZeroItem *zero() { if (!mZero) mZero = KDevPG::zero(); return mZero; } Model::TerminalItem *terminal(QString __name) { QString name = __name; TerminalSet::iterator it = terminals.find(name); if (it == terminals.end()) return KDevPG::terminal(__name, __name); return (*it); } void pushRule(Model::Node *rule) { Model::EvolveItem *e = nodeCast(rule); Q_ASSERT(e != nullptr); rules.push_back(e); } void pushParserClassMember(Model::Node *member) { Settings::MemberItem *m = nodeCast(member); Q_ASSERT(m != nullptr); if (m->mMemberKind == Settings::MemberItem::ConstructorCode) parserclassMembers.constructorCode.push_back(m); else if (m->mMemberKind == Settings::MemberItem::DestructorCode) parserclassMembers.destructorCode.push_back(m); else // public, protected or private declaration parserclassMembers.declarations.push_back(m); } void pushLexerClassMember(Model::Node *member) { Settings::MemberItem *m = nodeCast(member); Q_ASSERT(m != nullptr); if (m->mMemberKind == Settings::MemberItem::ConstructorCode) lexerclassMembers.constructorCode.push_back(m); else if (m->mMemberKind == Settings::MemberItem::DestructorCode) lexerclassMembers.destructorCode.push_back(m); else // public, protected or private declaration lexerclassMembers.declarations.push_back(m); } Model::TerminalItem *pushTerminal(QString __name, QString __description) { QString name = __name; TerminalSet::iterator it = terminals.find(name); if (it == terminals.end()) it = terminals.insert(name, KDevPG::terminal(__name, __description)); return (*it); } Model::SymbolItem *pushSymbol(QString __name) { QString name = __name; SymbolSet::iterator it = symbols.find(name); if (it == symbols.end()) { it = symbols.insert(name, KDevPG::symbol(__name)); start.insert(*it); } else start.remove(*it); return (*it); } void pushParserDeclarationHeader(QString file) { parserDeclarationHeaders << file; } void pushParserBitsHeader(QString file) { parserBitsHeaders << file; } void pushAstHeader(QString file) { astHeaders << file; } void pushLexerBitsHeader(QString file) { lexerBitsHeaders << file; } void pushLexerDeclarationHeader(QString file) { lexerDeclarationHeaders << file; } inline static bool ruleComp(Model::Node *a, Model::Node *b) { if(a != nullptr && a->kind == Model::NodeKindEvolve) a = ((Model::EvolveItem*)a)->mSymbol; if(b != nullptr && b->kind == Model::NodeKindEvolve) b = ((Model::EvolveItem*)b)->mSymbol; return a < b; } void finishedParsing() { std::sort(rules.begin(), rules.end(), &ruleComp); } Model::EvolveItem *searchRule(Model::SymbolItem *sym) { auto i = std::lower_bound(rules.begin(), rules.end(), sym, &ruleComp); if(i == rules.end() || (*i)->mSymbol != sym) return nullptr; return *i; } FirstSet::iterator firstBegin() { return firstSet.begin(); } FirstSet::iterator firstEnd() { return firstSet.end(); } FollowSet::iterator followBegin() { return followSet.begin(); } FollowSet::iterator followEnd() { return followSet.end(); } NodeSet &first(Model::Node *node, int K = 1) { return firstSet[qMakePair(node, K)]; } NodeSet &follow(Model::Node *node, int K = 1) { return followSet[qMakePair(node, K)]; } FollowDep &followDep(Model::Node *node) { return followDeps[node]; } FirstSet::iterator findInFirst(Model::Node *node, int K = 1) { return firstSet.find(qMakePair(node, K)); } FollowSet::iterator findInFollow(Model::Node *node, int K = 1) { return followSet.find(qMakePair(node, K)); } QSet start; Model::ZeroItem *mZero; SymbolSet symbols; TerminalSet terminals; QList rules; MemberCode parserclassMembers, lexerclassMembers; AstBaseClasses astBaseClasses; QString parserBaseClass, lexerBaseClass; QMap > lexerEnvs; QMap lexerEnvResults; QMap > lexerActions; QMap regexpById; QMap enteringCode, leavingCode; QMap dfaForNfa; Environment env; private: FirstSet firstSet; FollowSet followSet; FollowDeps followDeps; }; bool reducesToEpsilon(Model::Node *node); bool isZero(Model::Node *node); extern KDevPG::World globalSystem; extern QFile file; } QTextStream& operator << (QTextStream& out, KDevPG::Model::Node const *__node); #endif // KDEV_PG_H diff --git a/kdev-pg/test/op.g b/kdev-pg/test/op.g index 695fb68..2f1e3b1 100644 --- a/kdev-pg/test/op.g +++ b/kdev-pg/test/op.g @@ -1,40 +1,40 @@ [: -#include +#include #include :] %parserclass (protected declaration) [: void expectedSymbol(Op::AstNode::AstNodeKind kind, const QString& name); void expectedToken(int kind, enum TokenType tok, const QString& name); :] %token PLUS ("+"), MUL ("*"), INV ("-"), NUM ("123"), POW ("^"), BR ("BREAK"), NOT ("NOT"), L_PAREN ("("), R_PAREN (")"), QUESTION ("?"), COLON (":") ;; #expr=expr @ BR -> document ;; NUM -> number ;; %< number %bin PLUS 2 %left %bin MUL 4 %left %pre NOT 3 %post INV 1 %bin POW 5 %right %paren L_PAREN R_PAREN %tern QUESTION COLON 1 %left %> expr ;; [: #include "Optokentext.h" namespace Op { void Parser::expectedSymbol(Op::AstNode::AstNodeKind kind, const QString& name) { kDebug() << "In AstNode " << kind << ": Expected symbol " << name << " Token: " << tokenText(yytoken) << "(" << yytoken << ", \"" << "\"). Position: " << tokenStream->index(); abort(); } void Parser::expectedToken(int kind, enum TokenType tok, const QString& name) { kDebug() << "Read Token: " << tokenText(kind) << "(" << kind << ", \"" << "\"). Expected token " << name << " (" << tok << ")"; abort(); } } :] diff --git a/kdev-pg/test/op2.g b/kdev-pg/test/op2.g index df07b08..8e2f6cd 100644 --- a/kdev-pg/test/op2.g +++ b/kdev-pg/test/op2.g @@ -1,82 +1,82 @@ [: -#include +#include #include :] %parserclass (public declaration) [: QString token(int pos = 1); :] %parser_bits_header "Op2tokenstream.h" %parserclass (protected declaration) [: void expectedSymbol(Op2::AstNode::AstNodeKind kind, const QString& name); void expectedToken(int kind, enum TokenType tok, const QString& name); :] %parserclass (private declaration) [: QHash pre; QHash > post; QHash > bin; QHash > > tern; QHash paren; :] %token BR, PRE, POST, BIN, PAREN, TERN, LEFT, RIGHT, NUMBER, OPERATOR ;; (#line=line BR BR*)* -> document ;; ?(PRE [: op1 = token(); :] OPERATOR [: priority = token().toUInt(); :] NUMBER [: pre[op1] = priority; :] | POST [: op1 = token(); :] OPERATOR [: priority = token().toUInt(); :] NUMBER (LEFT [: isLeft = true; :] | RIGHT [: isLeft = false; :] | 0 [: isLeft = true; :] ) [: post[op1] = qMakePair(isLeft, priority); :] | BIN [: op1 = token(); :] OPERATOR [: priority = token().toUInt(); :] NUMBER (LEFT [: isLeft = true; :] | RIGHT [: isLeft = false; :] ) [: bin[op1] = qMakePair(isLeft, priority); :] | TERN [: op1 = token(); :] OPERATOR [: op2 = token(); :] OPERATOR [: priority = token().toUInt(); :] NUMBER (LEFT [: isLeft = true; :] | RIGHT [: isLeft = false; :] ) [: tern[op1] = qMakePair(op2, qMakePair(isLeft, priority)); :] | PAREN [: op1 = token(); :] OPERATOR [: op2 = token(); :] OPERATOR [: paren[op1] = op2; :] | expr=expr) -> line [ temporary variable isLeft: bool; temporary variable priority: uint; temporary variable op1: QString; temporary variable op2: QString; ] ;; NUMBER -> number ;; %< number %pre ?[: pre.contains(op = token()) :] OPERATOR %priority[: pre[op] :] %post ?[: post.contains(op = token()) :] OPERATOR %priority[: post[op].second :] %isLeft[: post[op].first :] %bin ?[: bin.contains(op = token()) :] OPERATOR %priority[: bin[op].second :] %isLeft[: bin[op].first :] %tern ?[: tern.contains(op = token()) :] OPERATOR ?[: tern[op].first == token() :] OPERATOR %priority[: tern[op].second.second :] %isLeft[: tern[op].second.first :] %paren ?[: paren.contains(op = token()) :] OPERATOR ?[: paren[op] == token() :] OPERATOR %> expr [ temporary variable op: QString; ];; [: #include "Op2tokentext.h" namespace Op2 { void Parser::expectedSymbol(Op2::AstNode::AstNodeKind kind, const QString& name) { kDebug() << "In AstNode " << kind << ": Expected symbol " << name << " Token: " << tokenText(yytoken) << "(" << yytoken << ", \"" << "\"). Position: " << tokenStream->index(); abort(); } void Parser::expectedToken(int kind, enum TokenType tok, const QString& name) { kDebug() << "Read Token: " << tokenText(kind) << "(" << kind << ", \"" << "\"). Expected token " << name << " (" << tok << ")"; abort(); } QString Parser::token(int pos) { return reinterpret_cast(tokenStream) ->tokenString(tokenStream->index() + pos - 2); } } :] diff --git a/tests/benchmarks.cpp b/tests/benchmarks.cpp index 27239b5..510a17b 100644 --- a/tests/benchmarks.cpp +++ b/tests/benchmarks.cpp @@ -1,361 +1,361 @@ /* Copyright 2009 Milian Wolff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "benchmarks.h" #include #include #include #include #include #include "../include/kdev-pg-location-table.h" -#include -#include +#include +#include using namespace std; namespace KDevPG { class BenchmarkLocationTable : public LocationTable { public: BenchmarkLocationTable() : LocationTable(), m_lastLine(0) { /// number of lines in each table const int lines = 12500; /// every i-th line has i chars, which gets reset each \p charResetLine line. const int charResetLine = 160; tableMaxOffset = 0; for ( int i = 0; i < lines; ++i ) { tableMaxOffset += tableMaxOffset % charResetLine + 1; newline(tableMaxOffset); } } /** * Implements a bisection algorithm / binary search * for the offset. * * Should perform pretty good for any kind of usage, but potentially not * as good as positionAtWithMemory for linear access. */ void positionAtQtBisection(qint64 offset, qint64 *line, qint64 *column) const { if ( offset < 0 ) { *line = -1; *column = -1; return; } else if ( offset > lines[currentLine - 1] ) { *line = currentLine - 1; *column = offset - lines[currentLine - 1]; return; } qint64 i = -1; // search relative to last line (next line and the one after that) if ( m_lastLine + 1 < currentLine && lines[m_lastLine] <= offset ) { if ( lines[m_lastLine + 1] > offset ) { // last matched line matches again i = m_lastLine; } else if ( m_lastLine + 2 < currentLine && lines[m_lastLine + 2] > offset ) { // next line relative to last matched matches i = m_lastLine + 1; } } if ( i == -1 ) { // fallback to binary search qint64 *it = std::lower_bound(lines, lines + currentLine, offset); Q_ASSERT(it != lines + currentLine); if (*it != offset) { --it; } *line = it - lines; *column = offset - *it; } else { *line = i; *column = offset - lines[i]; } m_lastLine = *line; } /** * Uses old algorithm as written by Roberto Raggi in r687144 (kdevelop-pg/include/kdev-pg-location-table.h) */ void positionAtSTLBisection(qint64 offset, qint64 *line, qint64 *column) const { if ( offset < 0 ) { *line = -1; *column = -1; return; } else if ( offset > lines[currentLine - 1] ) { *line = currentLine - 1; *column = offset - lines[currentLine - 1]; return; } qint64 i = -1; // search relative to last line (next line and the one after that) if ( m_lastLine + 1 < currentLine && lines[m_lastLine] <= offset ) { if ( lines[m_lastLine + 1] > offset ) { // last matched line matches again i = m_lastLine; } else if ( m_lastLine + 2 < currentLine && lines[m_lastLine + 2] > offset ) { // next line relative to last matched matches i = m_lastLine + 1; } } if ( i == -1 ) { // fallback to binary search qint64 *it = std::lower_bound(lines, lines + currentLine, offset); Q_ASSERT(it != lines + currentLine); if (*it != offset) { --it; } *line = it - lines; *column = offset - *it; } else { *line = i; *column = offset - lines[i]; } m_lastLine = *line; } qint64 tableMaxOffset; private: mutable qint64 m_lastLine; }; void Benchmarks::initTestCase() { srand ( time(nullptr) ); } void Benchmarks::positionAt() { QFETCH(int, algorithm); QFETCH(int, access); BenchmarkLocationTable table; qint64 line; qint64 column; switch ( algorithm) { case CurrentPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } case QtBinaryPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtQtBisection(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtQtBisection(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } case STLBinaryPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtSTLBisection(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtSTLBisection(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } } } void Benchmarks::positionAt_data() { QTest::addColumn("algorithm"); QTest::addColumn("access"); QTest::newRow("current, linear") << (int) CurrentPositionAt << (int) LinearAccess; QTest::newRow("current, random") << (int) CurrentPositionAt << (int) RandomAccess; QTest::newRow("qt binary, linear") << (int) QtBinaryPositionAt << (int) LinearAccess; QTest::newRow("qt binary, random") << (int) QtBinaryPositionAt << (int) RandomAccess; QTest::newRow("stl binary, linear") << (int) STLBinaryPositionAt << (int) LinearAccess; QTest::newRow("stl binary, random") << (int) STLBinaryPositionAt << (int) RandomAccess; } void Benchmarks::verifyPositionAt() { QFETCH(int, algorithm); QFETCH(int, access); BenchmarkLocationTable table; qint64 oldLine; qint64 oldColumn; qint64 newLine; qint64 newColumn; switch ( algorithm) { case QtBinaryPositionAt: { switch ( access ) { case LinearAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &oldLine, &oldColumn); table.positionAtQtBisection(i, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } // special cases // underflow table.positionAt(-5, &oldLine, &oldColumn); table.positionAtQtBisection(-5, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); // overflow table.positionAt(table.tableMaxOffset + 10, &oldLine, &oldColumn); table.positionAtQtBisection(table.tableMaxOffset + 10, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); break; } case RandomAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { qint64 offset = rand() % table.tableMaxOffset; table.positionAt(offset, &oldLine, &oldColumn); table.positionAtQtBisection(offset, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } break; } default: qFatal("unexpected access type"); break; } break; } case STLBinaryPositionAt: { switch ( access ) { case LinearAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &oldLine, &oldColumn); table.positionAtSTLBisection(i, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } // special cases // underflow table.positionAt(-5, &oldLine, &oldColumn); table.positionAtSTLBisection(-5, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); // overflow table.positionAt(table.tableMaxOffset + 10, &oldLine, &oldColumn); table.positionAtSTLBisection(table.tableMaxOffset + 10, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); break; } case RandomAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { qint64 offset = rand() % table.tableMaxOffset; table.positionAt(offset, &oldLine, &oldColumn); table.positionAtSTLBisection(offset, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } break; } default: qFatal("unexpected access type"); break; } break; } default: qFatal("unexpected algorithm"); break; } } void Benchmarks::verifyPositionAt_data() { QTest::addColumn("algorithm"); QTest::addColumn("access"); QTest::newRow("qt binary, linear") << (int) QtBinaryPositionAt << (int) LinearAccess; QTest::newRow("qt binary, random") << (int) QtBinaryPositionAt << (int) RandomAccess; QTest::newRow("stl binary, linear") << (int) STLBinaryPositionAt << (int) LinearAccess; QTest::newRow("stl binary, random") << (int) STLBinaryPositionAt << (int) RandomAccess; } } QTEST_MAIN(KDevPG::Benchmarks) diff --git a/tests/benchmarks.h b/tests/benchmarks.h index 3dd768c..ff10db4 100644 --- a/tests/benchmarks.h +++ b/tests/benchmarks.h @@ -1,55 +1,55 @@ /* Copyright 2009 Milian Wolff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef BENCHMARKS_H #define BENCHMARKS_H -#include +#include namespace KDevPG { class Benchmarks : public QObject { Q_OBJECT public Q_SLOTS: void initTestCase(); private Q_SLOTS: /// benchmarks on of the PositionAtAlgorithms void positionAt(); void positionAt_data(); /// verifies the new PositionAtAlgorithms by comparing to /// the initial algorithm void verifyPositionAt(); void verifyPositionAt_data(); private: enum PositionAtAlgorithms { CurrentPositionAt, QtBinaryPositionAt, STLBinaryPositionAt }; enum AccessType { LinearAccess, RandomAccess }; }; } #endif // BENCHMARKS_H diff --git a/tests/testlocationtable.cpp b/tests/testlocationtable.cpp index ab4c625..c515171 100644 --- a/tests/testlocationtable.cpp +++ b/tests/testlocationtable.cpp @@ -1,101 +1,101 @@ /* Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "testlocationtable.h" #include -#include -#include +#include +#include #include "../include/kdev-pg-location-table.h" namespace KDevPG { void TestLocationTable::initTestCase() { } void TestLocationTable::newline() { LocationTable table; qint64 offset = 100; table.newline(offset); qint64 line; qint64 column; table.positionAt(offset, &line, &column); QCOMPARE(line, 0ll); QCOMPARE(column, offset); } void TestLocationTable::normalAccess() { LocationTable table; table.newline(10); table.newline(20); qint64 line; qint64 column; qint64 myOffset = 15; table.positionAt(myOffset, &line, &column); QCOMPARE(line, 1ll); QCOMPARE(column, myOffset - table[1]); table.positionAt(0, &line, &column); QCOMPARE(line, 0ll); QCOMPARE(column, 0ll); } void TestLocationTable::overflow() { LocationTable table; table.newline(10); table.newline(20); qint64 line; qint64 column; qint64 myOffset = 200; table.positionAt(myOffset, &line, &column); QCOMPARE(line, 2ll); QCOMPARE(column, myOffset - table[2]); } void TestLocationTable::underflow() { LocationTable table; table.newline(10); table.newline(20); qint64 line; qint64 column; { table.positionAt(-1, &line, &column); QCOMPARE(line, -1ll); QCOMPARE(column, -1ll); } { table.positionAt(-1123, &line, &column); QCOMPARE(line, -1ll); QCOMPARE(column, -1ll); } } } QTEST_MAIN(KDevPG::TestLocationTable) diff --git a/tests/testlocationtable.h b/tests/testlocationtable.h index d165a83..d52d01a 100644 --- a/tests/testlocationtable.h +++ b/tests/testlocationtable.h @@ -1,44 +1,44 @@ /* Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TESTLOCATIONTABLE_H #define TESTLOCATIONTABLE_H -#include +#include namespace KDevPG { class TestLocationTable : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void underflow(); void newline(); void overflow(); void normalAccess(); }; } #endif // TESTLOCATIONTABLE_H diff --git a/tests/testmemorypool.cpp b/tests/testmemorypool.cpp index ba6242e..b1b1dc0 100644 --- a/tests/testmemorypool.cpp +++ b/tests/testmemorypool.cpp @@ -1,51 +1,51 @@ /* Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "testmemorypool.h" #include -#include -#include +#include +#include #include "../include/kdev-pg-memory-pool.h" namespace KDevPG { void TestMemoryPool::initTestCase() { } void TestMemoryPool::bigAlloc() { MemoryPool pool; size_t chunkSize = 256; unsigned int chunks = 10000; for ( unsigned int i = 0; i < chunks; ++i ) { pool.allocate(chunkSize); } } } QTEST_MAIN(KDevPG::TestMemoryPool) diff --git a/tests/testmemorypool.h b/tests/testmemorypool.h index a1accbf..aa80c55 100644 --- a/tests/testmemorypool.h +++ b/tests/testmemorypool.h @@ -1,41 +1,41 @@ /* Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TESTMEMORYPOOL_H #define TESTMEMORYPOOL_H -#include +#include namespace KDevPG { class TestMemoryPool : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void bigAlloc(); }; } #endif // TESTMEMORYPOOL_H