除了文档里面的要求,还有一些隐藏要求已经被确认了。
我是用的Free Pascal IDE,以及Vscode,Vscode可以下载pascal的编译和格式插件,然后在user setting
里面设置变量,格式化之后代码格式就会很整齐。
用{[^}]+}
正则表达式替换空,可以去掉所有的注释。
用^\s*(?=\r?$)\n
正则表达式替换空,可以去掉所有的空行。
part1的要求就是可以运行就行了。
首先是program PL0 ( input, output);
,第一行参数可要可不要,可以随后在后面设置,其中有一行代码page(output);
代表着输出文件到output里面,可以直接删掉,因为page
没有定义。然后在一开始var
申明里面加上fin,fout: text;
,然后直接全局替换掉input即可,顺便加上sfile,dfile: string;
用于表示文件名。在主程序里面加上下面代码,打开文件流。
writeln('please input source program file name : ');
readln(sfile);
assign(fin,sfile);
reset(fin);
writeln('please input the file name to save result : ');
readln(dfile);
assign(fout,dfile);
rewrite(fout);
这样在每个writeln后面都加上一个文件流输入语句就可以了,比如像下面一样。
writeln( '****', ' ':cc-1, '^', n:2 );
writeln(fout,'****', ' ':cc-1, '^', n:2);
主要是引号和减号,全部替换成英文的就可以了。
主要是两个,都在这行里object = (constant, variable, procedure);
,object
和procedure
,这两个都是pascal
语言的保留字,所以用这个两个变量名肯定会报错,所以改成objecttyp
和prosedure
,以防冲突,另外代码中的其他部分也需要替换,但是不能全局替换,因为有的是使用pascal
的procedure
,所以这部分改起来很麻烦。
直接删掉就好了,一共三条语句。
代码中有的符号很不友好,主要是下面三个符号
ssym[‘≠’] := neq;
ssym[‘≤’] := leq;
ssym[‘≥’] := geq;
具体使用是将≠
改成<>
,将≤
改成<=
,将≥
改成>=
。然后这三行直接删掉就可以了。相应的在pl0源程序里面要把符号改掉。改掉之后要增加符号的识别语句,可以在识别:=
的语句后面模仿写下如下代码,这样可以识别新加的三个符号。
Else If ch = '<'
Then
Begin
getch;
If ch = '='
Then
Begin
sym := leq;
getch
End
Else If ch = '>'
Then
Begin
sym := neq;
getch
End
Else sym := lss
End
Else If ch = '>'
Then
Begin
getch;
If ch = '='
Then
Begin
sym := geq;
getch
End
Else sym := gtr
End
将代码以前内容改成小写
word[1] := 'begin ';
word[2] := 'call ';
word[3] := 'const ';
word[4] := 'do ';
word[5] := 'end ';
word[6] := 'if ';
word[7] := 'odd ';
word[8] := 'procedure ';
word[9] := 'then ';
word[10] := 'var ';
word[11] := 'while ';
这句话原本是没有Not
的,所以只读一句话就结束了。
While Not eoln(fin) Do
这个处理程序原本也是没有Not
的
Procedure test( s1,s2 :symset; n: integer );
Begin
If Not ( sym In s1 )
Then
Begin
error(n);
s1 := s1+s2;
While Not( sym In s1) Do
getsym
End
End;
这行原本也没有Not
Until Not (sym In declbegsys);
这行原本也没有Not
If Not (sym In [eql, neq, lss, leq, gtr, geq]) Then
主要是加write和read语句
pl0源程序修改为一下内容,并且用这个文件测试
procedure test;
var input;
begin
read(input);
write(input);
end;
begin
call test;
end.
首先Const norw = 11;
改成Const norw = 13;
,因为要新加两个保留字。
然后修改
word[1] := 'begin ';
word[2] := 'call ';
word[3] := 'const ';
word[4] := 'do ';
word[5] := 'end ';
word[6] := 'if ';
word[7] := 'odd ';
word[8] := 'procedure ';
word[9] := 'read ';
word[10] := 'then ';
word[11] := 'var ';
word[12] := 'while ';
word[13] := 'write ';
wsym[1] := beginsym;
wsym[2] := callsym;
wsym[3] := constsym;
wsym[4] := dosym;
wsym[5] := endsym;
wsym[6] := ifsym;
wsym[7] := oddsym;
wsym[8] := procsym;
wsym[9] := readsym;
wsym[10] := thensym;
wsym[11] := varsym;
wsym[12] := whilesym;
wsym[13] := writesym;
mnemonic[lit] := 'LIT ';
mnemonic[opr] := 'OPR ';
mnemonic[lod] := 'LOD ';
mnemonic[sto] := 'STO ';
mnemonic[cal] := 'CAL ';
mnemonic[int] := 'INT ';
mnemonic[jmp] := 'JMP ';
mnemonic[jpc] := 'JPC ';
mnemonic[red] := 'RED ';
mnemonic[wrt] := 'WRT ';
在解释程序里面加
red :
Begin
writeln('Input a integer:');
writeln(fout,'Input a integer:');
readln(s[base(l)+a]);
writeln(fout,s[base(l)+a]);
End;
wrt :
Begin
writeln('Here is the integer:');
writeln(s[t]);
writeln(fout,'Here is the integer:');
writeln(fout,s[t]);
t := t+1
End
在condition
里面加
Else If sym = readsym
Then
Begin
getsym;
If sym = lparen
Then
Repeat
getsym;
If sym = ident
Then
Begin
i := position(id);
If i = 0
Then error(11)
Else If table[i].kind <> variable
Then
Begin
error(12);
i := 0
End
Else With table[i] Do
gen(red,lev-level,adr)
End
Else error(4);
getsym;
Until sym <> comma
Else error(40);
If sym <> rparen
Then error(22);
getsym
End
Else If sym = writesym
Then
Begin
getsym;
If sym = lparen
Then
Begin
Repeat
getsym;
expression([rparen,comma]+fsys);
gen(wrt,0,0);
Until sym <> comma;
If sym <> rparen
Then error(22);
getsym
End
Else error(40)
End;
参考博客
项目地址