All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.clips.Clips.g Maven / Gradle / Ivy

The newest version!
grammar Clips;

@parser::header {
    package org.drools.clips;

    import org.drools.clips.*;
    
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.HashMap;
    import java.util.Set;
    import java.util.HashSet;
    import java.util.StringTokenizer;
    import org.drools.lang.descr.*;
    import org.drools.lang.Location;
}

@parser::members {
    private PackageDescr packageDescr;
    private List errors = new ArrayList();
    private String source = "unknown";
    private int lineOffset = 0;
    private DescrFactory factory = new DescrFactory();
    private boolean parserDebug = false;
    private Location location = new Location( Location.LOCATION_UNKNOWN );

    public void setParserDebug(boolean parserDebug) {
        this.parserDebug = parserDebug;
    }

    public void debug(String message) {
        if ( parserDebug )
            System.err.println( "drl parser: " + message );
    }

    public void setSource(String source) {
        this.source = source;
    }
    public DescrFactory getFactory() {
        return factory;
    }

    public String getSource() {
        return this.source;
    }

    public PackageDescr getPackageDescr() {
        return packageDescr;
    }

    private int offset(int line) {
        return line + lineOffset;
    }

    /**
     * This will set the offset to record when reparsing. Normally is zero of course
     */
    public void setLineOffset(int i) {
         this.lineOffset = i;
    }

    private String getString(Token token) {
        String orig = token.getText();
        return orig.substring( 1, orig.length() -1 );
    }

    public void reportError(RecognitionException ex) {
        // if we've already reported an error and have not matched a token
        // yet successfully, don't report any errors.
        if ( state.errorRecovery ) {
            //System.err.print("[SPURIOUS] ");
            return;
        }
        state.syntaxErrors++; // don't count spurious
        state.errorRecovery = true;

        ex.line = offset(ex.line); //add the offset if there is one
        errors.add( ex );
    }

         /** return the raw RecognitionException errors */
         public List getErrors() {
             return errors;
         }

         /** Return a list of pretty strings summarising the errors */
         public List getErrorMessages() {
             List messages = new ArrayList();
         for ( Iterator errorIter = errors.iterator() ; errorIter.hasNext() ; ) {
                      messages.add( createErrorMessage( (RecognitionException) errorIter.next() ) );
                  }
                  return messages;
         }

         /** return true if any parser errors were accumulated */
         public boolean hasErrors() {
          return ! errors.isEmpty();
         }

         /** This will take a RecognitionException, and create a sensible error message out of it */
         public String createErrorMessage(RecognitionException e)
        {
        StringBuffer message = new StringBuffer();
                message.append( source + ":"+e.line+":"+e.charPositionInLine+" ");
                if ( e instanceof MismatchedTokenException ) {
                        MismatchedTokenException mte = (MismatchedTokenException)e;
                        message.append("mismatched token: "+
                                                           e.token+
                                                           "; expecting type "+
                                                           tokenNames[mte.expecting]);
                }
                else if ( e instanceof MismatchedTreeNodeException ) {
                        MismatchedTreeNodeException mtne = (MismatchedTreeNodeException)e;
                        message.append("mismatched tree node: "+
                                                           //mtne.foundNode+ FIXME
                                                           "; expecting type "+
                                                           tokenNames[mtne.expecting]);
                }
                else if ( e instanceof NoViableAltException ) {
                        NoViableAltException nvae = (NoViableAltException)e;
            message.append( "Unexpected token '" + e.token.getText() + "'" );
                        /*
                        message.append("decision=<<"+nvae.grammarDecisionDescription+">>"+
                                                           " state "+nvae.stateNumber+
                                                           " (decision="+nvae.decisionNumber+
                                                           ") no viable alt; token="+
                                                           e.token);
                                                           */
                }
                else if ( e instanceof EarlyExitException ) {
                        EarlyExitException eee = (EarlyExitException)e;
                        message.append("required (...)+ loop (decision="+
                                                           eee.decisionNumber+
                                                           ") did not match anything; token="+
                                                           e.token);
                }
                else if ( e instanceof MismatchedSetException ) {
                        MismatchedSetException mse = (MismatchedSetException)e;
                        message.append("mismatched token '"+
                                                           e.token+
                                                           "' expecting set "+mse.expecting);
                }
                else if ( e instanceof MismatchedNotSetException ) {
                        MismatchedNotSetException mse = (MismatchedNotSetException)e;
                        message.append("mismatched token '"+
                                                           e.token+
                                                           "' expecting set "+mse.expecting);
                }
                else if ( e instanceof FailedPredicateException ) {
                        FailedPredicateException fpe = (FailedPredicateException)e;
                        message.append("rule "+fpe.ruleName+" failed predicate: {"+
                                                           fpe.predicateText+"}?");
                } else if (e instanceof GeneralParseException) {
            message.append(" " + e.getMessage());
        }
                   return message.toString();
        }   
        
        void checkTrailingSemicolon(String text, int line) {
            if (text.trim().endsWith( ";" ) ) {
                this.errors.add( new GeneralParseException( "Trailing semi-colon not allowed", offset(line) ) );
            }
        }
        
            void addTypeFieldDescr(LispForm lispForm, TypeDeclarationDescr typeDescr) {
                if ( !(lispForm.getSExpressions()[0] instanceof SymbolLispAtom) ) {
                    throw new RuntimeException("should specify a slot");
                }

                SymbolLispAtom slot = (SymbolLispAtom) lispForm.getSExpressions()[0];
                if ( !"slot".equals( slot.getValue().trim() )) {
                    throw new RuntimeException("should specify a slot");
                }

                if ( !(lispForm.getSExpressions()[1] instanceof SymbolLispAtom) ) {
                    throw new RuntimeException("should specify a slot name");
                }
                SymbolLispAtom slotName = (SymbolLispAtom) lispForm.getSExpressions()[1];

                if ( !(lispForm.getSExpressions()[2] instanceof LispForm) ) {
                    throw new RuntimeException("should specify a type");
                }

                LispForm typeForm = (LispForm) lispForm.getSExpressions()[2];
                if ( !(typeForm.getSExpressions()[0] instanceof SymbolLispAtom) ) {
                    throw new RuntimeException("should specify a type");
                }
                SymbolLispAtom type = (SymbolLispAtom) typeForm.getSExpressions()[0];
                if ( !"type".equals( type.getValue().trim() )) {
                    throw new RuntimeException("should specify a type");
                }

                if ( !(typeForm.getSExpressions()[1] instanceof SymbolLispAtom) ) {
                    throw new RuntimeException("should specify a slot name");
                }
                SymbolLispAtom typeName = (SymbolLispAtom) typeForm.getSExpressions()[1];

                TypeFieldDescr fieldDescr = new TypeFieldDescr(removeQuotes(slotName.getValue()), new PatternDescr(removeQuotes(typeName.getValue())));
                typeDescr.addField( fieldDescr );
            }

            String removeQuotes(String string) {
                return string.substring( 1, string.length() -1 );
            }
      
}

@lexer::header {
    package org.drools.clips;
}

/*
opt_semicolon
    : ';'?
    ;


compilation_unit
    :
        ( statement )+
    ;
*/
/*
statement
    :
    //later we add the other possible statements here
    (  //do something with the returned rule here )
    ;
*/		
/* prolog
    @init {
        String packageName = "";
    }
    :	( n=package_statement { packageName = n; } )?
        {
            this.packageDescr = factory.createPackage( packageName );
        }
    ;

statement
    :
    (	import_statement
    |       function_import_statement
    |	global
    |	function
    |       t=template {this.packageDescr.addFactTemplate( t ); }
    |	r=rule { if( r != null ) this.packageDescr.addRule( r ); }
    |	q=query	{ if( q != null ) this.packageDescr.addRule( q ); }
    )
    ;

package_statement returns [String packageName]
    @init{
        packageName = null;
    }
    :
        PACKAGE n=dotted_name[null] opt_semicolon
        {
            packageName = n;
        }
    ;
*/

eval[ParserHandler handler]
    :
       (		  i=importDescr{ handler.importHandler( i ); }
                | f=deffunction { handler.functionHandler( f ); }
                | t=deftemplate { handler.templateHandler( t ); }
                | r=defrule { handler.ruleHandler( r ); }
                | form=lisp_form { handler.lispFormHandler( form ); }
        )*
    ;

    /*
eval_sExpressions[MVELClipsContext context] returns[List list]
    @init {
        list = new ArrayList();
    }
    :
        (  	a=lisp_list { list.add( a ); }
           | a=deffunction { FunctionHandlers.dump(a, null, context); }
        )*
//		{ sExpressions = ( SExpression[] ) list.toArray( new SExpression[ list.size () ] ); }
    ;
    */

importDescr returns[ImportDescr importDescr]
    : LEFT_PAREN 'import' importName=NAME { importDescr = new ImportDescr( importName.getText() ); } RIGHT_PAREN
    ;
/*	


execution_list returns[ExecutionEngine engine]
    @init {
            engine = new BlockExecutionEngine();
            BuildContext context = new ExecutionBuildContext( engine, functionRegistry );
    }

    :
        (fc=lisp_list[context, new LispForm(context) ] { context.addFunction( (FunctionCaller) fc ); })
    ;
*/	

/*
deffunction returns[Deffunction function]
    @init {
            BuildContext context = null;
    }
    :	loc=LEFT_PAREN
          DEFFUNCTION
          ruleName=NAME {
            function = new Deffunction( ruleName.getText() );
            functionRegistry.addFunction( function );
              context = new ExecutionBuildContext( function, functionRegistry );
          }
        loc=LEFT_PAREN
         (v=VAR {
            context.addVariable( function.addParameter( v.getText() ) );
         })*
          RIGHT_PAREN
          (fc=lisp_list[context, new LispForm(context) ] { context.addFunction( (FunctionCaller) fc ); })*
          RIGHT_PAREN
    ;
*/	

/*	
deffunction_params[BuildContext context]
    :	loc=LEFT_PAREN
         (v=VAR {
            // this creates a parameter on the underlying function
             context.createLocalVariable( v.getText() );
         })*
          RIGHT_PAREN
    ;
*/

deffunction returns[FunctionDescr functionDescr]
    @init {
        List content = null;
        functionDescr = null;
    }
    :	LEFT_PAREN
        t=DEFFUNCTION //{ list.add( new SymbolLispAtom( t.getText() ) ); }    	//deffunction
        name=lisp_atom //name
        params=lisp_form  // params
        (form=lisp_form { if ( content == null ) content = new ArrayList(); content.add( form ); } )+
        RIGHT_PAREN
        { functionDescr = FunctionHandlers.createFunctionDescr( name, params, content ); }
        //{ sExpression = new LispForm( ( SExpression[] ) list.toArray( new SExpression[ list.size () ] ) ); }
    ;

defrule returns [RuleDescr rule]
    @init {
            rule = null;
            AndDescr lhs = null;
            PatternDescr colum = null;
            Set declarations = null;  
          }
    :	loc=LEFT_PAREN

        DEFRULE ruleName=NAME
          {
              debug( "start rule: " + ruleName.getText() );
              String ruleStr = ruleName.getText();
              AttributeDescr module = null;

            if ( ruleStr.indexOf("::") >= 0 ) {
                String mod = ruleStr.substring(0, ruleStr.indexOf("::"));
                ruleStr = ruleStr.substring(ruleStr.indexOf("::")+2);
                module = new AttributeDescr( "agenda-group", mod );
                module.setLocation( offset(ruleName.getLine()), ruleName.getCharPositionInLine() );
                module.setStartCharacter( ((CommonToken)ruleName).getStartIndex() );
                module.setEndCharacter( ((CommonToken)ruleName).getStopIndex() );
            }

            rule = new RuleDescr( ruleStr, null );
            if( module != null ) {
                rule.setNamespace( module.getValue() );
                rule.addAttribute( module );
            }

            rule.setLocation( offset(loc.getLine()), loc.getCharPositionInLine() );
            rule.setStartCharacter( ((CommonToken)loc).getStartIndex() );

            // not sure how you define where a LHS starts in clips, so just putting it here for now
            lhs = new AndDescr();
              rule.setLhs( lhs );
            lhs.setLocation( offset(loc.getLine()), loc.getCharPositionInLine() );
            lhs.setStartCharacter( ((CommonToken)loc).getStartIndex() );

            rule.addAttribute( new AttributeDescr( "dialect", "clips") );

            declarations = new HashSet();
        }
        documentation=STRING {
            // do nothing here for now
        }
        ruleAttribute[rule]

        ce[lhs, declarations]*

        '=>'

        list=rule_consequence{ rule.setConsequence( list ); }

        RIGHT_PAREN
    ;

rule_consequence returns[List list]
    @init {
        list = null;
    }
    :	
        (l=lisp_form	{ if ( list == null ) list = new ArrayList(); list.add( l ); })*
    ;

ruleAttribute[RuleDescr rule]
    :
        ( LEFT_PAREN 'declare'
            ( LEFT_PAREN d=salience { rule.addAttribute( d ); } RIGHT_PAREN )?
        RIGHT_PAREN )?
    ;

salience returns [AttributeDescr d ]
    @init {
        d = null;
    }
    :
        loc=SALIENCE i=INT
        {
            d = new AttributeDescr( "salience", i.getText() );
            d.setLocation( offset(loc.getLine()), loc.getCharPositionInLine() );
            d.setStartCharacter( ((CommonToken)loc).getStartIndex() );
            d.setEndCharacter( ((CommonToken)i).getStopIndex() );
        }
    ;


ce[ConditionalElementDescr in_ce, Set declarations]
    :	(   and_ce[in_ce, declarations]
          | or_ce[in_ce, declarations]
          | not_ce[in_ce, declarations]
          | exists_ce[in_ce, declarations]
           | eval_ce[in_ce, declarations]
          | normal_pattern[in_ce, declarations]
          | bound_pattern[in_ce, declarations]
        )
    ;

and_ce[ConditionalElementDescr in_ce, Set declarations]
    @init {
        AndDescr andDescr= null;        
    }
    :	LEFT_PAREN
        AND {
            andDescr = new AndDescr();
            in_ce.addDescr( andDescr );
        }
        ce[andDescr, declarations]+
        RIGHT_PAREN
    ;

or_ce[ConditionalElementDescr in_ce, Set declarations]
    @init {
        OrDescr orDescr= null;         
    }
    :	LEFT_PAREN
        OR {
            orDescr = new OrDescr();
            in_ce.addDescr( orDescr );
        }
        ce[orDescr, declarations]+
        RIGHT_PAREN
    ;

not_ce[ConditionalElementDescr in_ce, Set declarations]
    @init {
        NotDescr notDescr= null;         
    }
    :	LEFT_PAREN
        NOT {
            notDescr = new NotDescr();
            in_ce.addDescr( notDescr );
        }
        ce[notDescr, declarations]
        RIGHT_PAREN
    ;

exists_ce[ConditionalElementDescr in_ce, Set declarations]
    @init {
        ExistsDescr existsDescr= null;        
    }
    :	LEFT_PAREN
        EXISTS {
            existsDescr = new ExistsDescr();
            in_ce.addDescr( existsDescr );
        }
        ce[existsDescr, declarations]
        RIGHT_PAREN
    ;

eval_ce[ConditionalElementDescr in_ce, Set declarations]
    :	LEFT_PAREN
        TEST
        t=lisp_form { EvalDescr evalDescr = new EvalDescr(); evalDescr.setContent( t ); in_ce.addDescr( evalDescr ); }
        RIGHT_PAREN
    ;

normal_pattern[ConditionalElementDescr in_ce, Set declarations]
    @init {
        PatternDescr pattern = null;
        ConditionalElementDescr top = null;
    }
    :	LEFT_PAREN
        name=NAME {
            pattern = new PatternDescr(name.getText());
            in_ce.addDescr( pattern );
            top = pattern.getConstraint();

        }
        field_constriant[top, declarations]*
        RIGHT_PAREN
    ;



bound_pattern[ConditionalElementDescr in_ce, Set declarations]
    @init {
        PatternDescr pattern = null;
        String identifier = null;
        ConditionalElementDescr top = null;        
    }
    :	var=VAR {
            identifier = var.getText();
        }
        ASSIGN_OP LEFT_PAREN name=NAME
        {
            pattern = new PatternDescr(name.getText());
            pattern.setIdentifier( identifier.replace( '?', '$') );
            in_ce.addDescr( pattern );
            top = pattern.getConstraint();
        }
        field_constriant[top, declarations]*
        RIGHT_PAREN
    ;

field_constriant[ConditionalElementDescr base, Set declarations] 
    @init {
         List list = new ArrayList();
        FieldBindingDescr fbd = null;
        FieldConstraintDescr fc = null;
        RestrictionConnectiveDescr top = null;
        String op = "==";
    }
    :
        LEFT_PAREN f=NAME
        {
            fc = new FieldConstraintDescr(f.getText());
            fc.setLocation( offset(f.getLine()), f.getCharPositionInLine() );
            fc.setStartCharacter( ((CommonToken)f).getStartIndex() );
            //base.addDescr( fc );
            top = fc.getRestriction();
        }

        or_restr_connective[top, base, fc, declarations]
        { if ( top.getRestrictions().size() != 0 ) {
            base.insertBeforeLast( PredicateDescr.class, fc );
          }
        }
        RIGHT_PAREN
    ;
/*	
connected_constraint[RestrictionConnectiveDescr rc, ConditionalElementDescr base]
    :
    restriction[rc, base]
    (
        AMPERSAND { rc.addRestriction(new RestrictionConnectiveDescr(RestrictionConnectiveDescr.AND)); }
        connected_constraint[rc, base]
    |
        PIPE {rc.addRestriction(new RestrictionConnectiveDescr(RestrictionConnectiveDescr.OR)); }
        connected_constraint[rc, base]
    )?
    ;
*/


or_restr_connective[ RestrictionConnectiveDescr rcBase, ConditionalElementDescr ceBase, FieldConstraintDescr fcBase, Set declarations ]
    options {
        backtrack=true;
    }
    @init {
        RestrictionConnectiveDescr or = new RestrictionConnectiveDescr(RestrictionConnectiveDescr.OR);
    }
    :
        and_restr_connective[or, ceBase, fcBase, declarations]
        (
            options {backtrack=true;}
            : PIPE
            {
                location.setType(Location.LOCATION_LHS_INSIDE_CONDITION_OPERATOR);
            }
            and_restr_connective[or, ceBase, fcBase, declarations]
        )*
    ;
    finally {
            if( or.getRestrictions().size() == 1 ) {
                    $rcBase.addOrMerge( (RestrictionDescr) or.getRestrictions().get( 0 ) );
            } else if ( or.getRestrictions().size() > 1 ) {
                $rcBase.addRestriction( or );
            }
    }

and_restr_connective[ RestrictionConnectiveDescr rcBase, ConditionalElementDescr ceBase, FieldConstraintDescr fcBase, Set declarations ]
    @init {
        RestrictionConnectiveDescr and = new RestrictionConnectiveDescr(RestrictionConnectiveDescr.AND);
    }
    :
        restriction[and, ceBase, fcBase, declarations]
        ( AMPERSAND restriction[and, ceBase, fcBase, declarations] )*
        /*
        (	options {backtrack=true;}
        :	t=AMPERSAND
            {
                location.setType(Location.LOCATION_LHS_INSIDE_CONDITION_OPERATOR);
            }
            restriction[and, ceBase]
        )*
        */
    ;
    finally {
            if( and.getRestrictions().size() == 1) {
                    $rcBase.addOrMerge( (RestrictionDescr) and.getRestrictions().get( 0 ) );
            } else if ( and.getRestrictions().size() > 1 ) {
                $rcBase.addRestriction( and );
            }
    }

restriction[RestrictionConnectiveDescr rc, ConditionalElementDescr base, FieldConstraintDescr fcBase, Set declarations ]
    @init {
            String op = "==";
    }
    :	(TILDE{op = "!=";})?
        (	predicate_constraint[rc, op, base]
          |	return_value_restriction[op, rc]
          |	variable_restriction[op, rc, base, fcBase, declarations]
          | 	lc=literal_restriction {
                         rc.addRestriction( new LiteralRestrictionDescr(op, lc) );
                      op = "==";
                }
        )
    ;

predicate_constraint[RestrictionConnectiveDescr rc, String op, ConditionalElementDescr base]	
    :	COLON
        t=lisp_form { $base.addDescr( new PredicateDescr( t ) ); }

    ;


return_value_restriction[String op, RestrictionConnectiveDescr rc]
    :	EQUALS
        t=lisp_form {rc.addRestriction( new ReturnValueRestrictionDescr (op, t ) ); }
    ;

//will add a declaration field binding, if this is the first time the name  is used		
variable_restriction[String op, RestrictionConnectiveDescr rc, ConditionalElementDescr ceBase, FieldConstraintDescr fcBase, Set declarations ]
    @init { String identifier = null;}
    :	VAR {
            identifier =  $VAR.text.replace( '?', '$');
            if ( declarations.contains( identifier) ) {
                rc.addRestriction( new VariableRestrictionDescr(op, identifier ) );
             } else {
                 FieldBindingDescr fbd = new FieldBindingDescr();
                 fbd.setIdentifier( identifier );
                 fbd.setFieldName( fcBase.getFieldName() );
                 ceBase.addDescr( fbd );
                 declarations.add( identifier );
             }
        }
    ;


literal_restriction returns [String text]
    @init {
        text = null;
    }
    :
        t=literal {
            text = t;
        }
    ;

/* 
eval_sExpressions[MVELClipsContext context] returns[List list]
    @init {
        list = new ArrayList();
    }
    :
        (  	a=lisp_list { list.add( a ); }
           | a=deffunction { FunctionHandlers.dump(a, null, context); }
        )*
//		{ sExpressions = ( SExpression[] ) list.toArray( new SExpression[ list.size () ] ); }
    ;
*/	
lisp_form returns[LispForm lispForm]
    @init {
        List list = new ArrayList();
        lispForm = null;
    }
    :	LEFT_PAREN

        (
            t=NAME { list.add( new SymbolLispAtom( t.getText() ) ); }
            |
            t=VAR { list.add( new VariableLispAtom( t.getText() ) ); }
        )
        (		a=lisp_atom	{ list.add( a ); }
            |	l=lisp_form	{ list.add( l ); }
        )*
        RIGHT_PAREN
        { lispForm = new LispForm( ( SExpression[] ) list.toArray( new SExpression[ list.size () ] ) ); }
    ;

lisp_atom returns[SExpression sExpression] 
    @init {
        sExpression  =  null;
    }
    :
        (
                 t=VAR		{ sExpression = new VariableLispAtom( t.getText() ); }
            |	t=STRING	{ sExpression = new StringLispAtom( getString( t ) ); }
            |	t=FLOAT		{ sExpression = new FloatLispAtom( t.getText() ); }
            |	t=INT		{ sExpression = new IntLispAtom( t.getText() ); }
            | 	t=BOOL		{ sExpression = new BoolLispAtom( t.getText() ); }
            | 	t=NULL		{ sExpression = new NullLispAtom( null ); }
            |   t=NAME		{ sExpression = new SymbolLispAtom( "\"" +t.getText() + "\""); }

        )
    ;


deftemplate returns[TypeDeclarationDescr typeDescr]
    :
    loc=LEFT_PAREN 
    DEFTEMPLATE deftemplateName=NAME	{ 	  			  		
              debug( "start rule: " + deftemplateName.getText() );
              String templateStr = deftemplateName.getText();

            String mod = null;
            if ( templateStr.indexOf("::") >= 0 ) {
                mod = templateStr.substring(0, templateStr.indexOf("::"));
                templateStr = templateStr.substring(templateStr.indexOf("::")+2);
            }

            typeDescr = new TypeDeclarationDescr( templateStr );
            if( mod != null ) {
                typeDescr.setNamespace( mod );
            }

            typeDescr.setLocation( offset(loc.getLine()), loc.getCharPositionInLine() );
            typeDescr.setStartCharacter( ((CommonToken)loc).getStartIndex() );

        }    

    documentation=STRING {
        // do nothing here for now
    }

        /*
        // can't get this to work, so process manually as a lisp_form
    (LEFT_PAREN     
    'slot' slotName=NAME
        LEFT_PAREN 
             'type' slotType=NAME {
            typeDescr.addField( new TypeFieldDescr(slotName.getText(), new PatternDescr( slotType.getText() ) ) );
        }        
        RIGHT_PAREN 
    RIGHT_PAREN)*
    */

    (list=lisp_form { addTypeFieldDescr(list, typeDescr); })*

    RIGHT_PAREN
    ;   


literal returns [String text]
    @init {
        text = null;
    }
    :	(   t=STRING { text = getString( t ); }
          | t=NAME     { text = t.getText(); }
          | t=INT    { text = t.getText(); }
          | t=FLOAT	 { text = t.getText(); }
          | t=BOOL 	 { text = t.getText(); }
          | t=NULL   { text = null; }
        )
    ;

WS      :       (	' '
                |	'\t'
                |	'\f'
                |	EOL
                )
                { $channel=HIDDEN; }
        ;                      

     
DEFTEMPLATE :   'deftemplate';
  
//SLOT        :	'slot';       
DEFRULE		:	'defrule';
DEFFUNCTION :	'deffunction';
OR 			:	'or';
AND 		:	'and';
NOT 		:	'not';
EXISTS 		:	'exists';
TEST 		:	'test';
NULL		:	'null';

DECLARE 	:	'declare';        		

SALIENCE	:	'salience';

//MODIFY  :	'modify';

fragment
EOL 	:	     
           (       ( '\r\n' )=> '\r\n'  // Evil DOS
                |       '\r'    // Macintosh
                |       '\n'    // Unix (the right way)
                )
        ;  
        
INT	
    :	('-')?('0'..'9')+
    ;

FLOAT
    :	('-')?('0'..'9')+ '.' ('0'..'9')+
    ;

STRING
    :  ('"' ( EscapeSequence | ~('\\'|'"') )* '"')
     | ('\'' ( EscapeSequence | ~('\\'|'\'') )* '\'')
    ;

fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
EscapeSequence
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UnicodeEscape
    |   OctalEscape
    ;

fragment
OctalEscape
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UnicodeEscape
    :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit
    ;

BOOL
    :	('true'|'false')
    ;

VAR 	: '?' SYMBOL_CHAR+
        ;            

SH_STYLE_SINGLE_LINE_COMMENT	
    :	'#' ( options{greedy=false;} : .)* EOL /* ('\r')? '\n'  */
                { $channel=HIDDEN; }
    ;
        
        
C_STYLE_SINGLE_LINE_COMMENT	
    :	'//' ( options{greedy=false;} : .)* EOL // ('\r')? '\n'
                { $channel=HIDDEN; }
    ;


LEFT_PAREN
    :	'('
    ;

RIGHT_PAREN
    :	')'
    ;
        
LEFT_SQUARE
    :	'['
    ;

RIGHT_SQUARE
    :	']'
    ;

LEFT_CURLY
    :	'{'
    ;

RIGHT_CURLY
    :	'}'
    ;

TILDE	:	'~'
    ;

AMPERSAND 
    :	'&'
    ;

PIPE
    :	'|'
    ;

ASSIGN_OP 
    :	'<-'
    ;

COLON	:	':';

EQUALS	:	'=';	
        
MULTI_LINE_COMMENT
    :	'/*' (options{greedy=false;} : .)* '*/'
                { $channel=HIDDEN; }
    ;

NAME :	SYMBOL ;

fragment
SYMBOL : FIRST_SYMBOL_CHAR SYMBOL_CHAR* ;	

// allowed <
// not allowed ?
fragment
FIRST_SYMBOL_CHAR : ('a'..'z'|'A'..'Z'|'0'..'9'|'!'|'$'|'%'|'^'|'*'|'_'|'-'|'+'|'='|'\\'|'/'|'@'|'#'|':'|'>'|'<'|','|'.'|'['|']'|'{'|'}');	

// allowed ? 
// not allowed <
fragment
SYMBOL_CHAR : ('a'..'z'|'A'..'Z'|'0'..'9'|'!'|'$'|'%'|'^'|'*'|'_'|'-'|'+'|'='|'\\'|'/'|'@'|'#'|':'|'>'|','|'.'|'['|']'|'{'|'}'|'?');		




© 2015 - 2025 Weber Informatics LLC | Privacy Policy