rustlr 0.3.0

LR/LALR parser generator that can automatically create abstract syntax trees
Documentation
using System;
using System.Text;

class Sample
{
public static void Main(String[] argv)
  {
  String [] args = Environment.GetCommandLineArgs();
  System.IO.FileStream f = new System.IO.FileStream(args[1], System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read, 8192);
  Yylex yy = new Yylex(f);
  /*Yytoken*/LexToken t;
  while ((t = yy.yylex()) != null && t.token_type!="EOF")
    Console.WriteLine(t);
  }
}

class Utility {
  public static void assert
   (
   bool expr
   )
    {
      /*
    if (false == expr)
      throw new ApplicationException("Error: Assertion failed.");
      */
      Console.WriteLine("Assertion Failed");
    }
  
  private static String[] errorMsg = new String[]
    {
    "Error: Unmatched end-of-comment punctuation.",
    "Error: Unmatched start-of-comment punctuation.",
    "Error: Unclosed string.",
    "Error: Illegal character."
    };
  
  public const int E_ENDCOMMENT = 0; 
  public const int E_STARTCOMMENT = 1; 
  public const int E_UNCLOSEDSTR = 2; 
  public const int E_UNMATCHED = 3; 

  public static void error
    (
    int code
    )
    {
    Console.WriteLine(errorMsg[code]);
    }
  }
/* LexToken class in absLexer.dll, from absLexer.cs */ 

%%

%type LexToken
%eofval{
  return new LexToken("EOF","EOF",yyline,yychar);
%eofval}  
%{
private static int comment_count = 0;
%} 
%line
%char
%state COMMENT

ALPHA=[A-Za-z]
DIGIT=[0-9]
DIGITS=[0-9]+
HEXDIGITS=(0x)[0-9A-Fa-f]*
NEWLINE=((\r\n)|\n)
NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012]
WHITE_SPACE_CHAR=[{NEWLINE}\ \t\b\012]
STRING_TEXT=(\\\"|[^{NEWLINE}\"]|\\{WHITE_SPACE_CHAR}+\\)*
COMMENT_TEXT=([^*/\r\n]|[^*\r\n]"/"[^*\r\n]|[^/\r\n]"*"[^/\r\n]|"*"[^/\r\n]|"/"[^*\r\n])*
ALPHANUM=[A-Za-z][A-Za-z0-9_]*


%% 

<YYINITIAL> "," { return (new LexToken("COMMA",yytext(),yyline,yychar)); }
<YYINITIAL> ";" { return new LexToken("SEMICOLON",yytext(),yyline,yychar); }
<YYINITIAL> "(" { return new LexToken("LPREN",yytext(),yyline,yychar); }
<YYINITIAL> ")" { return new LexToken("RPAREN",yytext(),yyline,yychar); }  

<YYINITIAL> {NONNEWLINE_WHITE_SPACE_CHAR}+ { return null; }

<YYINITIAL,COMMENT> [(\r\n?|\n)] { return null; }

<YYINITIAL> "/*" { yybegin(COMMENT); comment_count = comment_count + 1; return null;
}

<COMMENT> "/*" { comment_count = comment_count + 1; return null;
}
<COMMENT> "*/" { 
	comment_count = comment_count - 1; 
	Utility.assert(comment_count >= 0);
	if (comment_count == 0) {
    		yybegin(YYINITIAL);
		}
        return null;
}

<COMMENT> {COMMENT_TEXT} { return null; }

<YYINITIAL> \"{STRING_TEXT}\" {
	String str =  yytext().Substring(1,yytext().Length - 1);
	
	Utility.assert(str.Length == yytext().Length - 2);
	/*return (new Yytoken(40,str,yyline,yychar,yychar + str.Length));*/
        return new LexToken("StrLit",str,yyline,yychar);
}
<YYINITIAL> \"{STRING_TEXT} {
	String str =  yytext().Substring(1,yytext().Length);

	Utility.error(Utility.E_UNCLOSEDSTR);
	Utility.assert(str.Length == yytext().Length - 1);
	/*return (new Yytoken(41,str,yyline,yychar,yychar + str.Length));*/
        return new LexToken("Unclosed String",str,yyline,yychar);
} 
<YYINITIAL> {DIGIT}+ { 
        return new LexToken("Integer",Int32.Parse(yytext()),yyline,yychar);
}	
<YYINITIAL> {ALPHA}({ALPHA}|{DIGIT}|_)* {
        return new LexToken("Alphanumeric",yytext(),yyline,yychar);
}	
<YYINITIAL,COMMENT> . {
	StringBuilder sb = new StringBuilder("Illegal character: <");
	String s = yytext();
	for (int i = 0; i < s.Length; i++)
	  if (s[i] >= 32)
	    sb.Append(s[i]);
	  else
	    {
	    sb.Append("^");
	    sb.Append(Convert.ToChar(s[i]+'A'-1));
	    }
        sb.Append(">");
	Console.WriteLine(sb.ToString());	
	Utility.error(Utility.E_UNMATCHED);
        return null;
}