“预期的EOF”自定义编译器中的错误 [英] "Expected EOF" error in custom compiler

查看:99
本文介绍了“预期的EOF”自定义编译器中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在C#中使用一个名为algebra的自定义语言编写自己的编译器。

我正在学习本教程http://msdn.microsoft.com/en-us/magazine/cc136756。 aspx



这是编译器的源代码。

我认为编译器代码有问题。

代码很大所以我把它作为下载链接附加,如果你不想下载它们,你可以查看教程代码,因为我的代码基本相同。







https://www.dropbox.com/s/6h5fu7f6in3mtfw/Ast.cs

https ://www.dropbox.com/s/lt6x8zjltq68q50/Parser.cs

https://www.dropbox.com/s/h84crc42472773s/Program.cs

https ://www.dropbox.com/s/gkw2im5n1it28pb/Scanner.cs

https://www.dropbox.com/s/0gnx65to6pfna0y/CodeGen.cs





这是创建消息的代码(Parser.cs):



  public  Parser(Collections.IList< object>代币)
{
.tokens = tokens;
.index = 0 ;
this .result = this .ParseStmt();

if this .index!= this .tokens.Count)
throw new System.Exception ( 期望的EOF);
}



此代码扫描任何操作员标志(以'+'为例)(scanner.c)

顺便说一下,还有更多的代码。



 case'+':
input.Read();
this.result.Add(Scanner.Add);
休息;



这个位只是一个枚举(Ast.cs)



  //  < bin_op> := + | -  | * | /  
public enum BinOp
{
Add ,
Sub,
Mul,
Div
}





CodeGen.cs



  private   void  GenExpr(Expr expr,System.Type expectedType)
{
System.Type deliveredType;

if (expr StringLiteral)
{
deliverType = typeof string );
this .il.Emit(Emit.OpCodes.Ldstr,((StringLiteral)expr).Value);
}
else if (expr IntLiteral)
{
deliverType = typeof int );
this .il.Emit(Emit.OpCodes.Ldc_I4,((IntLiteral)expr).Value);
}
else if (expr 变量)
{
string ident =((Variable)expr).Ident;
deliveredType = this .TypeOfExpr(expr);

if (!this.symbolTable.ContainsKey(ident))
{
throw new System.Exception( 未声明的变量' + ident + ');
}

this .il.Emit(Emit.OpCodes.Ldloc, this .symbolTable [IDENT]);
}

else if (stmt 打印)
{





这些是'写'和'读''语句



  //  write语句是System.Console.WriteLine的别名。 
// 它使用字符串大小写
this .GenExpr(((Print)stmt).Expr, typeof string ));
this .il.Emit(Emit.OpCodes.Call, typeof (System.Console) .GetMethod( WriteLine new System.Type [] { typeof string )}));
}

else if (stmt ReadInt)
{
this .il.Emit(Emit.OpCodes.Call, typeof (System.Console).GetMethod( ReadLine,System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null new 系统.Type [] {}, null ));
this .il.Emit(Emit.OpCodes.Call, typeof int )。GetMethod( Parse,System.Reflection .BindingFlags.Public | System.Reflection.BindingFlags.Static, null new System.Type [] { typeof string )}, null ) );
this .Store(((ReadInt)stmt).Ident, typeof INT ));
}





此处更多代码定义变量,表达式等。



  / *  < expr> :=< string> 
* | < INT>
* | < arith_expr>
* | < IDENT>
* /

public abstract class Expr
{
}

// < string> :=< string_elem> *
public class StringLiteral:Expr
{
public string 值;
}

// < int> :=< digit> +
public class IntLiteral:Expr
{
public int 值;
}

// < ident> :=< char> < ident_rest> *
// < ident_rest> :=< char> | < digit>
public class 变量:Expr
{
public string Ident;
}

// < bin_expr> :=< expr> < bin_op> < expr>
public class BinExpr:Expr
{
public Expr Left;
public Expr Right;
public BinOp Op;
}





关于运营商的更多信息(scanner.c)/ / b $ b < pre lang =c#> #region ArithmiticConstants

// 表示arithmitic标记的常量。这可以
// 或者写成枚举。
public static readonly object Add = new object ();
public static readonly < span class =code-keyword> object Sub = new object ();
public static readonly < span class =code-keyword> object Mul = new object ();
public static readonly < span class =code-keyword> object Div = new object ();
public static readonly < span class =code-keyword> object Semi = new object ();
public static readonly < span class =code-keyword> object Equal = new object ();

#endregion





问题看起来无法对数字或变量执行任何数学运算。



所以例如我写这样的代码并尝试编译它然而我得到一个错误(预期的EOF):



变量x = 9;

变量y = 10;

变量ans = x * y;

写ans;



这里输出应该是90但是编译器给出错误'EOF预期'

但是这样可行:



变量x = 9;

写x;



所以我可以确认语言有效







如果有人能帮助我,我将非常感激。

所以我很感激我得到的任何帮助。谢谢:)

解决方案

so I am making my own compiler in C# for a custom Language called algebra.
I am following this tutorial http://msdn.microsoft.com/en-us/magazine/cc136756.aspx

Here is the source code of the compiler.
I think there is something wrong with the compiler code.
The code is quite big so I attach it as download links, if you don't want to download them you can look at the tutorial code as the code I have is basically the same.



https://www.dropbox.com/s/6h5fu7f6in3mtfw/Ast.cs
https://www.dropbox.com/s/lt6x8zjltq68q50/Parser.cs
https://www.dropbox.com/s/h84crc42472773s/Program.cs
https://www.dropbox.com/s/gkw2im5n1it28pb/Scanner.cs
https://www.dropbox.com/s/0gnx65to6pfna0y/CodeGen.cs


Here is the code that creates the message(Parser.cs):

public Parser(Collections.IList<object> tokens)
  {
      this.tokens = tokens;
      this.index = 0;
      this.result = this.ParseStmt();

      if (this.index != this.tokens.Count)
          throw new System.Exception("expected EOF");
  }


This code scans for any operator signs(taking '+' as an example)(scanner.cs)
there is more code to this by the way.

case '+':
                input.Read();
                this.result.Add(Scanner.Add);
                break;


This bit is just an enumeration(Ast.cs)

// <bin_op> := + | - | * | /
public enum BinOp
{
Add,
Sub,
Mul,
Div
}



CodeGen.cs

private void GenExpr(Expr expr, System.Type expectedType)
  {
      System.Type deliveredType;

      if (expr is StringLiteral)
      {
          deliveredType = typeof(string);
          this.il.Emit(Emit.OpCodes.Ldstr, ((StringLiteral)expr).Value);
      }
      else if (expr is IntLiteral)
      {
          deliveredType = typeof(int);
          this.il.Emit(Emit.OpCodes.Ldc_I4, ((IntLiteral)expr).Value);
      }
      else if (expr is Variable)
      {
          string ident = ((Variable)expr).Ident;
          deliveredType = this.TypeOfExpr(expr);

          if (!this.symbolTable.ContainsKey(ident))
          {
              throw new System.Exception("undeclared variable '" + ident + "'");
          }

          this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[ident]);
      }

  else if (stmt is Print)
      {



These are the 'write' and 'read' statements

// the "write" statement is an alias for System.Console.WriteLine.
           // it uses the string case
           this.GenExpr(((Print)stmt).Expr, typeof(string));
           this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) }));
       }

       else if (stmt is ReadInt)
       {
           this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null));
           this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null));
           this.Store(((ReadInt)stmt).Ident, typeof(int));
       }



more code here that defines variables ,expressions etc.

/* <expr> := <string>
    *  | <int>
    *  | <arith_expr>
    *  | <ident>
    */
   public abstract class Expr
   {
   }

   // <string> := " <string_elem>* "
   public class StringLiteral : Expr
   {
    public string Value;
   }

   // <int> := <digit>+
   public class IntLiteral : Expr
   {
   public int Value;
   }

   // <ident> := <char> <ident_rest>*
   // <ident_rest> := <char> | <digit>
   public class Variable : Expr
   {
   public string Ident;
   }

   // <bin_expr> := <expr> <bin_op> <expr>
   public class BinExpr : Expr
   {
   public Expr Left;
   public Expr Right;
   public BinOp Op;
   }



More on the operators (scanner.cs)

#region ArithmiticConstants

// Constants to represent arithmitic tokens. This could
// be alternatively written as an enum.
public static readonly object Add = new object();
public static readonly object Sub = new object();
public static readonly object Mul = new object();
public static readonly object Div = new object();
public static readonly object Semi = new object();
public static readonly object Equal = new object();

#endregion



the problem looks like it's not possible to perform any mathematical operations on either a number or variable.

so for example I write such code and try to compile it however I get an error(expected EOF):

variable x = 9;
variable y = 10;
variable ans = x * y;
write ans;

here the output should be 90 however the compiler gives an error 'EOF expected'
However this works:

variable x = 9;
write x;

so I can confirm the language works



I would be very grateful if anyone could help me.
So I appreciate any help that I get. Thanks :)

解决方案

这篇关于“预期的EOF”自定义编译器中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆