命令行参数问题

4
我有一个批处理文件,它使用名为ASET.exe(http://www.pement.org/sed/bat_env.htm)的外部程序来为变量设置值。之所以使用它是因为它具有比普通SET命令更高级的功能。ASET可以将给定的字符串更改为不同的格式,然后将其分配给变量。它拥有类似于UPPER()、Fread()、Lower()、left()的函数。
c:\test> aset var := left('asdf',2) 

上面的语句将“as”赋值给变量“var”。但问题在于它只能在Win 98或之前的机器上运行。它在Win NT、XP或2008中无法工作。因此,我决定像c#中的ASET一样编写一个小程序,支持一些少量的函数。我将这些命令作为命令行参数读取并解析它们,然后使用for循环和switch case,以达到某种程度上的期望结果。但我无法正确解析所有类型的命令。
例如:我无法正确解析以下命令:
aset var := left(upper(fsdsf),2). 

我的问题是:解析命令行参数的正确流程是什么?如何区分函数名、各种开关和运算符?使用“switch”是基于输入字符串调用函数的唯一解决方案吗?
这是我的语法文件。
grammar sra;

options {

  language = Java;
  output = AST;
}

start returns [String res]: expression 
{
$res=$expression.res;
System.out.println("value equals at start: "+$expression.text+$res);
} ;

expression returns [String res]
: Identifier Assignop statement
{$res=$statement.res;
System.out.println("value equals at ecpression: "+$statement.text+" "+$res);}
;

statement returns [String res]
  : function {$res=$function.res;
  System.out.println("value equals at statement: "+$function.text+" "+$res);}

  //|function Plus function
  //|function Plus Identifier
  //|Identifier
  //|Identifier Plus Identifier
  ;


   function returns [String res]
  : e=upper {$res=$e.res;
  System.out.println("value equals at function: "+$e.text+" "+$res);}  
  ;
upper returns [String res]
  : e=Upper '(' b=arguments   ')'
  {
  System.out.println("argum before conver "+$b.text);
  $res= ($b.text).toUpperCase();
  System.out.println("value equals at upper: "+$e.text+" "+"Arguments="+$b.text+" "+$res); }

  ;
arguments  returns [String res]     
                :   e1=Identifier   {$res=$e1.text;}
                |  function  {$res=$function.res;} 
                ;


Upper : 'upper';
Lower : 'lower';

Identifier  :  ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')*;
Assignop :':=' ;

Lparen  : '(';
Rparen  : ')';
Plus  : '+';
WS  : (' '|'\t'|'\r'|'\n')+{$channel = HIDDEN;};

现在该如何实现类似于 var := upper(upper(fsf)) 的功能呢?我得到的输出是 UPPER(FSF)。

1
它不能在XP或更高版本中工作的原因是因为它需要写入父进程的环境块。为什么不学习PowerShell甚至带有WSF的VBScript呢? - Ben
但我有许多使用ASET的批处理文件,我不想改变所有这些文件。 - Sravan
我找到了解决方案。我将以下行更改为 $res= ($b.res).toUpperCase();, 而不是 $res= ($b.text).toUpperCase(); - Sravan
2个回答

2
你可以按照自己的方式解析命令行参数。你提出的用法不是命令行参数的典型用法,因此对于你想做的事情,没有一个“正确”的过程。

你似乎有自己的语法想法(可能基于Pascal),所以你需要找到或编写一个针对你的语法的解析器和评估器。在一个极端是像ANTLR这样的东西,或者你可以在sprache中找到一些方法。

此外,值得一看的是http://commandline.codeplex.com/,其中包含了一些关于解析和处理命令行参数的想法(尽管我怀疑这不能满足你的要求)。


谢谢您的建议。我的需求很复杂吗?我会尝试学习ANTLR并使用它 :) - Sravan
看起来你想要能够评估从命令行传递的表达式-也许你可以通过简单的解析器来实现,但是如果不知道你想要支持的语法(我不知道aset的语法),我不能确定- 你可能可以通过Boo编译器/解释器来做一些事情。 - Martin Ernst
非常抱歉回复晚了,最近非常忙。在这段时间里,我尝试学习ANTLR,并且已经能够理解它的基础知识了。 - Sravan
我创建了一个小的语法文件。它只有一个函数。UPPER Upper(asdf)返回ASDF 现在我想要像upper(upper(asdf))返回ASDF这样的功能... 我该怎么做? - Sravan

0

Windows 98已经停止支持6年了,ASET也是如此。

你可以尝试看看"Take Command" (4NT)是否能做到你想要的,但我认为使用带FreeDOS的VirtualBox可能是最好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接