⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntax.g

📁 基于ANTLR的简单编译器源码version0.1
💻 G
字号:
header{
#include "ANTLRExt.h"
#include "data_type.h"
#include "symbols.h" 
#include <string>
using namespace std;
}

options{
  language="Cpp";
}

class Datalexer extends Lexer;
options
{                                                    
   charVocabulary = '\0'..'\377';                                 
   testLiterals=false;    
   defaultErrorHandler = false;
   k=4;                          
} 


APOSTROPHE  :'\'';
SEMI        :';';
COLON       :':';
ASSIGN      :'=';

protected DIGIT                   
  : '0'..'9';                                                    
                                                              
INT                                                               
options {                                                         
  paraphrase = "an integer value";                                
}                                                                 
	:    (DIGIT)+                  // base-10                       
             (  '.' (DIGIT)*                      	{$setType(DOUBLE);}
	         (('e' | 'E') ('+' | '-')? (DIGIT)+)?                   
	     |   ('e' | 'E') ('+' | '-')? (DIGIT)+   	{$setType(DOUBLE);}
             )?                                                   
	;                                                               

HEX
options {                                                         
  paraphrase = "a hexadecimal integer value";                                
}
   :'0' ('X'|'x')('a'..'f'|DIGIT|'A'..'F')+
   ;
	
DOUBLE                                                             
options {                                                         
  paraphrase = "an floating point value";                         
}
	:    '.' (DIGIT)+ (('e' | 'E') ('+' | '-')? (DIGIT)+)?          
    ; 

WS	:	(	' '
		|	'\t'
		|	'\f'
		// handle newlines
		|	(	"\r\n"  // Evil DOS
			|	'\r'    // Macintosh
			|	'\n'    // Unix (the right way)
			)
			{ newline(); }
		)
		{ _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; }
	;
	
IDENT
options {
  testLiterals = true;
  paraphrase = "an identifer";
}

	:	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
	;
	
BIT: 'b' APOSTROPHE ('0'|'1');

BITS:'B' APOSTROPHE ('0'|'1')+;

SL_COMMENT :                                     
	"//"                                           
	(~'\n')* '\n'                                  
	{ _ttype = antlr::Token::SKIP; newline(); }    
	;                                              
                                                 
ML_COMMENT                                       
	:	"/*"                                         
		(	{ LA(2)!='/' }? '*'                        
		|	'\n' { newline(); }                        
		|	~('*'|'\n')                                
		)*                                           
		"*/"                                         
			{ $setType(antlr::Token::SKIP); }          
	; 

CHAR
options {
  paraphrase = "a character literal";
}
	:
	'\''
	( ESC | ~'\'' )
	'\''
	;

STRING
options {
  paraphrase = "a string literal";
}
	:
	'"'
	(ESC|~'"')*
	'"'
	;

protected
ESC	:	'\\'
		(	'n'
		|	'r'
		|	't'
		|	'b'
		|	'f'
		|	'"'
		|	'\''
		|	'\\'
		|	'0'..'3'
			(
				options {
					warnWhenFollowAmbig = false;
				}
			:	DIGIT
				(
					options {
						warnWhenFollowAmbig = false;
					}
				:	DIGIT
				)?
			)?
		|	'4'..'7'
			(
				options {
					warnWhenFollowAmbig = false;
				}
			:	DIGIT
			)?
		)
	;
	
//#############################################################################
//#############################################################################		
class DataParser extends Parser;
options
 {
	genHashLines = true;		// include line number information
	buildAST = true;			// uses CommonAST by default   
	defaultErrorHandler = false;
	ASTLabelType = "RefASTNodeExt";  //uses user defination ASTNodeType
	k=3;
} 
tokens
{
 BLOCK;
 PROGRAM;
 DEFASSIGN;
}	

program        
    :(statement)*
	{## =#([PROGRAM, "PROGRAM"], ##);}
    ;

definition
    :var_def
    ;

var_def
    :type_name COLON!
	(
	  IDENT (ASSIGN! expression ) {## =#([DEFASSIGN, "DEFASSIGN"], ##);}
	  |IDENT  (COMMA! IDENT)*
	) SEMI!
	;	
	
const_value
   :BIT
   |BITS
   |INT 
   |HEX
   |DOUBLE  
   |CHAR
   |STRING
   |"true"
   |"false"
   ;

type_name
   :"bit"
   |"bits"
   |"uint8"
   |"char"
   |"string"
   |"uint16"
   |"int16"
   |"int"
   |"uint"
   |"float"
   |"double"
   |"bool"
   ;

block
  :LCURLY!
  (statement)*
  RCURLY!
  {## = #([BLOCK, "BLOCK"], ##);}
  ;
  
statement
  :definition
  |assign_statement
  |block
  ;   

expression
  :const_value
  |IDENT;  


assign_statement
   :IDENT  ASSIGN^ expression SEMI!
   ;   

//#############################################################################
//#############################################################################

class DataASTParser extends TreeParser;
options {
	defaultErrorHandler = false;
	ASTLabelType = "RefASTNodeExt"; 
}
{
  CSymTable  symtable;
/* define error deal with manner----whrow data type:class CompilerException */
   	void ERROR_IF(bool cond, int line, string msg) {
		if (cond) {
			throw CompilerException(line, msg);
		}
	}
}

program        
    :#(PROGRAM (statement)*)
    {
       symtable.SaveData("test.data");
    }
    ;

definition
    :var_def
    ;

var_def
{
TypeAttr t1,t2;  
}
    :#(DEFASSIGN 
	   t1=type_name 
	   id:IDENT 
	   t2=expression
	     {
		    if(t2.IsConvertable(t1))//t2 can convert to t1
			{
			   if(symtable.GetSymb(id->getText())==NULL)
			     symtable.AddSymb(t1,id->getText(),t2.value);			     
			   else
			     ERROR_IF(true, id->getLine(), "Identifier redefined!");
			}
			else
			   ERROR_IF(true, id->getLine(), "Data assign type error!");
		 }
	   )
	 |(t1=type_name 
	  (ids:IDENT
	    {
			if(symtable.GetSymb(id->getText())!=NULL)
			   ERROR_IF(false, id->getLine(), "Identifier redefined!");
			else	    
		       symtable.AddSymb(t1,ids->getText(),"");
		}
	   )*)	
	;	
	
const_value returns [TypeAttr t]
   :b:BIT
   		{
			t.SetType(BIT_T);
            t.SetValue(b->getText());
			t.BitToStr();//resolve bit to 0/1 string
		}    
   |bs:BITS
   		{
			t.SetType(BITS_T);
            t.SetValue(bs->getText());
			ERROR_IF(!t.BitsToStr(),bs->getLine(),"bits length>32!");
		}     
   |i:INT 
   		{			
			t.IsInt();
            t.SetValue(i->getText());
			t.CalcLen();
		}     
   |h:HEX
   		{			
			t.IsInt();
            t.SetValue(h->getText());
            t.HexToStr();			
		}    
   |d:DOUBLE 
   		{			
			t.IsDouble();
            t.SetValue(d->getText());
            t.CalcLen();			
		}      
   |c:CHAR
   		{
			t.SetType(CHAR_T);			
            t.SetValue(c->getText());
			t.CharToStr();
		}      
   |s:STRING
   		{
			t.SetType(STR_T);			
            t.SetValue(d->getText());
			t.StrToStr();
		}      
   |"true"
   		{
			t.SetType(BOOL_T);			
            t.SetValue("0");			
		}      
   |"false"
   		{
			t.SetType(BOOL_T);			
            t.SetValue("1");			
		}      
   ;

type_name  returns [TypeAttr t]
   :"bit" 
   		{
			t.SetType(BIT_T);			
		}   
   |"bits"
   		{
			t.SetType(BITS_T);			
		}    
   |"uint8"
   		{
			t.SetType(UCHAR_T);			
		}    
   |"char"
   		{
			t.SetType(CHAR_T);			
		}    
   |"string"
   		{
			t.SetType(STR_T);			
		}    
   |"uint16"
   		{
			t.SetType(UINT16_T);			
		}    
   |"int16"
   		{
			t.SetType(INT16_T);			
		}    
   |"int"
   		{
			t.SetType(INT_T);			
		}    
   |"uint"
   		{
			t.SetType(UINT_T);			
		}    
   |"float"
   		{
			t.SetType(FLOOT_T);			
		}    
   |"double"
   		{
			t.SetType(DOUBLE_T);			
		}    
   |"bool"
   		{
			t.SetType(BOOL_T);			
		}    
   ;

block
  :#(BLOCK (statement)*)
  ;
  
statement
  :definition
  |assign_statement
  |block
  ;   

expression returns [TypeAttr t]
{CSymbol* symb;}
  :t=const_value
  |id:IDENT 
    {
	   symb=symtable.GetSymb(id->getText());
	   bool temp=symb==NULL;
	   string errors="undefined identifier:"+id->getText();
	   ERROR_IF(temp,id->getLine(),errors);
	   t=symb->GetAttr();
	}; 

assign_statement
{
   CSymbol* symb;
   TypeAttr t1,t2;
}
   :#(ASSIGN id:IDENT  t2=expression)
    {
	   symb=symtable.GetSymb(id->getText());
	   if(symb==NULL)
	      ERROR_IF(true,id->getLine(),"undefined identifier!");	  
       else
       {	   
		   t1=symb->GetAttr();
		   if(t2.IsConvertable(t1))//t2 can convert to t1
		   {
				symtable.SetSymValue(id->getText(),t2.value);
		   }
		   else
				ERROR_IF(true, id->getLine(), "data type uncompatiable!");
	   }		
	} ;   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -