%{
//
// 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.Languages.MonoBASIC
{
using System.Text;
using System;
using System.Collections;
using CIR;
using Mono.Languages;
using Mono.Languages.MonoBASIC; // To get the tokenizer
///
/// The MonoBASIC Parser
///
public class Parser : GenericParser {
Namespace current_namespace;
TypeContainer current_container;
/*
///
/// 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;
*/
///
/// Used to record all types defined
///
Tree tree;
bool UseExtendedSyntax; // for ".mbs" files
public override string[] GetExtensions()
{
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 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 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 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_namespace_member_declarations
EOF
{
$$ = $3;
}
;
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 namespace_name EOL
{
current_namespace.Using ((string) $2);
}
;
opt_attributes
: /* empty */
;
namespace_declaration
: NAMESPACE qualified_identifier EOL
{
current_namespace = new Namespace (current_namespace, (string) $2);
}
opt_imports_directives
opt_namespace_member_declarations
END NAMESPACE EOL
{
current_namespace = current_namespace.Parent;
}
;
namespace_name
: qualified_identifier
;
opt_namespace_member_declarations
: /* empty */
| namespace_member_declarations
;
namespace_member_declarations
: namespace_member_declaration
| namespace_member_declarations namespace_member_declaration
;
namespace_member_declaration
: namespace_declaration
| type_declaration
{
int mod_flags = 0;
string name = "";
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;
}
;
type_declaration
: class_declaration
;
class_declaration
: /* opt_attributes opt_modifiers */
CLASS IDENTIFIER /* opt_class_interfaces */ EOL
{
}
opt_class_member_declarations
END CLASS EOL
{
}
;
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 override int parse ()
{
current_namespace = new Namespace (null, "");
this.tree = rc.Tree;
current_container = tree.Types;
current_container.Namespace = current_namespace;
UseExtendedSyntax = name.EndsWith(".mbs");
lexer = new Tokenizer (input, name);
StringBuilder value = new StringBuilder ();
global_errors = 0;
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);
global_errors++;
}
return global_errors;
}
/* end end end */
}