%{ // // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler // // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) // // Licensed under the terms of the GNU GPL // // Copyright (C) 2001 A Rafael D Teixeira // // TODO: // Nearly everything // namespace Mono.MonoBASIC { using System.Text; using System; using System.Collections; using Mono.Languages; using Mono.CSharp; /// /// The MonoBASIC Parser /// public class Parser : GenericParser { /* /// /// Current block is used to add statements as we find /// them. /// Block current_block; /// /// Current interface is used by the various declaration /// productions in the interface declaration to "add" /// the interfaces as we find them. /// Interface current_interface; /// /// This is used by the unary_expression code to resolve /// a name against a parameter. /// Parameters current_local_parameters; /// /// Using during property parsing to describe the implicit /// value parameter that is passed to the "set" accessor /// method /// Parameter [] implicit_value_parameters; */ bool UseExtendedSyntax; // for ".mbs" files public override string[] extensions() { string [] list = { ".vb", ".mbs" }; return list; } %} %token EOF %token NONE /* This token is never returned by our lexer */ %token ERROR // This is used not by the parser, but by the tokenizer. // do not remove. /* *These are the MonoBASIC keywords */ %token ADDHANDLER %token ADDRESSOF %token ALIAS %token AND %token ANDALSO %token ANSI %token AS %token ASSEMBLY %token AUTO %token BOOLEAN %token BYREF %token BYTE %token BYVAL %token CALL %token CASE %token CATCH %token CBOOL %token CBYTE %token CCHAR %token CDATE %token CDEC %token CDBL %token CHAR %token CINT %token CLASS %token CLNG %token COBJ //%token COMPARE %token CONST %token CSHORT %token CSNG %token CSTR %token CTYPE %token DATE %token DECIMAL %token DECLARE %token DEFAULT %token DELEGATE %token DESCRIPTION // MonoBASIC extension %token DIM %token DO %token DOUBLE %token EACH %token ELSE %token ELSEIF %token END %token ENUM %token EOL %token ERASE %token ERROR %token EVENT %token EXIT //%token EXPLICIT %token FALSE %token FINALLY %token FOR %token FRIEND %token FUNCTION %token GET %token GETTYPE %token GOTO %token HANDLES %token IF %token IMPLEMENTS %token IMPORTS %token IN %token INHERITS %token INTEGER %token INTERFACE %token IS %token LET %token LIB %token LIKE %token LONG %token LOOP %token ME %token MOD %token MODULE %token MUSTINHERIT %token MUSTOVERRIDE %token MYBASE %token MYCLASS %token NAMESPACE %token NEW %token NEXT %token NOT %token NOTHING %token NOTINHERITABLE %token NOTOVERRIDABLE %token OBJECT %token ON %token OPTION %token OPTIONAL %token OR %token ORELSE %token OVERLOADS %token OVERRIDABLE %token OVERRIDES %token PARAMETER // MonoBASIC extension %token PARAM_ARRAY %token PRESERVE %token PRIVATE %token PROPERTY %token PROTECTED %token PUBLIC %token RAISEEVENT %token READONLY %token REDIM %token REM %token REMOVEHANDLER %token RESUME %token RETURN %token SELECT %token SET %token SHADOWS %token SHARED %token SHORT %token SINGLE %token SIZEOF %token STATIC %token STEP %token STOP %token STRING %token STRUCTURE %token SUB %token SUMMARY // MonoBASIC extension %token SYNCLOCK %token THEN %token THROW %token TO %token TRUE %token TRY %token TYPEOF %token UNICODE %token UNTIL %token VARIANT %token WHEN %token WHILE %token WITH %token WITHEVENTS %token WRITEONLY %token XOR /* MonoBASIC single character operators/punctuation. */ %token OPEN_BRACKET "[" %token CLOSE_BRACKET "]" %token OPEN_PARENS "(" %token CLOSE_PARENS ")" %token DOT "." %token COMMA "," %token COLON ":" %token PLUS "+" %token MINUS "-" %token ASSIGN "=" %token OP_LT "<" %token OP_GT ">" %token STAR "*" %token PERCENT "%" %token DIV "/" %token OP_EXP "^" %token INTERR "?" %token OP_IDIV "\\" %token OP_CONCAT "&" /* MonoBASIC multi-character operators. */ %token OP_LE "<=" %token OP_GE ">=" %token OP_EQ "==" %token OP_NE "<>" %token OP_AND //"and" %token OP_OR //"or" %token OP_XOR //"xor" %token OP_MODULUS //"mod" %token OP_MULT_ASSIGN "*=" %token OP_DIV_ASSIGN "/=" %token OP_IDIV_ASSIGN "\\=" %token OP_ADD_ASSIGN "+=" %token OP_SUB_ASSIGN "-=" %token OP_CONCAT_ASSIGN "&=" %token OP_EXP_ASSIGN "^=" /* Numbers */ %token LITERAL_INTEGER "int literal" %token LITERAL_SINGLE "float literal" %token LITERAL_DOUBLE "double literal" %token LITERAL_DECIMAL "decimal literal" %token LITERAL_CHARACTER "character literal" %token LITERAL_STRING "string literal" %token IDENTIFIER /* Add precedence rules to solve dangling else s/r conflict */ %nonassoc LOWPREC %nonassoc IF %nonassoc ELSE %right ASSIGN %left OP_OR %left OP_AND %left BITWISE_OR %left BITWISE_AND %left OP_SHIFT_LEFT OP_SHIFT_RIGHT %left PLUS MINUS %left STAR DIV PERCENT %right BITWISE_NOT CARRET UMINUS %nonassoc OP_INC OP_DEC %left OPEN_PARENS %left OPEN_BRACKET OPEN_BRACE %left DOT %nonassoc HIGHPREC %start compilation_unit %% compilation_unit : opt_imports_directives opt_attributes opt_declarations EOF { $$ = $3; } ; opt_declarations : /* empty */ | declarations ; declarations : declaration | declarations declaration ; declaration : namespace_declaration | type_declaration { string name = ""; int mod_flags; if ($1 is Class){ Class c = (Class) $1; mod_flags = c.ModFlags; name = c.Name; } else if ($1 is Struct){ Struct s = (Struct) $1; mod_flags = s.ModFlags; name = s.Name; } else break; if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){ Report.Error ( 1527, lexer.Location, "Namespace elements cannot be explicitly " + "declared private or protected in '" + name + "'"); } } ; qualified_identifier : IDENTIFIER | qualified_identifier DOT IDENTIFIER { $$ = (($1).ToString ()) + "." + ($3.ToString ()); } ; opt_imports_directives : /* empty */ | imports_directives ; imports_directives : imports_directive | imports_directives imports_directive ; imports_directive : /* imports_alias_directive | */ imports_namespace_directive ; imports_namespace_directive : IMPORTS qualified_identifier EOL { current_namespace.Using ((string) $2, lexer.Location); } ; opt_attributes : /* empty */ ; namespace_declaration : NAMESPACE qualified_identifier EOL { current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2); } opt_imports_directives opt_declarations END NAMESPACE EOL { current_namespace = current_namespace.Parent; } ; type_declaration : class_declaration | module_declaration // | struct_declaration // | interface_declaration // | enum_declaration // | delegate_declaration ; class_declaration : /* opt_attributes opt_modifiers */ CLASS IDENTIFIER /* opt_class_interfaces */ EOL { } opt_class_member_declarations END CLASS EOL { } ; opt_module_modifiers : /* empty */ { $$ = (int) 0; } | PUBLIC { $$ = Modifiers.PUBLIC; } | FRIEND { $$ = Modifiers.INTERNAL; } ; module_declaration : opt_attributes opt_module_modifiers MODULE IDENTIFIER EOL { Module new_module; string name; name = MakeName((string) $4); new_module = new Module(current_container, name, (int) $2, (Attributes) $1, lexer.Location); current_container = new_module; current_container.Namespace = current_namespace; RootContext.Tree.RecordDecl(name, new_module); } opt_class_member_declarations END MODULE EOL { Module new_module = (Module)current_container; current_container = current_container.Parent; CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location); $$ = new_module; } ; opt_class_member_declarations : /* empty */ | class_member_declarations ; class_member_declarations : class_member_declaration | class_member_declarations class_member_declaration ; class_member_declaration : /* type_declaration | */ sub_declaration ; sub_declaration : SUB qualified_identifier OPEN_PARENS opt_formal_parameters CLOSE_PARENS EOL opt_statements END SUB EOL ; opt_statements : /* empty */ | qualified_identifier OPEN_PARENS opt_actual_parameters CLOSE_PARENS EOL ; opt_formal_parameters : /* empty */ | qualified_identifier AS qualified_identifier ; opt_actual_parameters : /* empty */ | qualified_identifier | LITERAL_STRING ; %% Tokenizer lexer; public Tokenizer Lexer { get { return lexer; } } public override int parse () { current_namespace = new Namespace (null, ""); current_container = RootContext.Tree.Types; current_container.Namespace = current_namespace; UseExtendedSyntax = name.EndsWith(".mbs"); lexer = new Tokenizer (input, name, defines); StringBuilder value = new StringBuilder (); try { if (yacc_verbose_flag) yyparse (lexer, new yydebug.yyDebugSimple ()); else yyparse (lexer); } catch (Exception e) { Console.WriteLine (lexer.location + " : Parsing error "); Console.WriteLine (e); } return Report.Errors; } /* end end end */ }