Syntax 如何制作语法操纵器?
首先,很抱歉问这个问题,我知道我听到了一些有用的消息,但我就是记不起来了 基本上,我想为编程语言创建自己的语法。例如,此代码:Syntax 如何制作语法操纵器?,syntax,Syntax,首先,很抱歉问这个问题,我知道我听到了一些有用的消息,但我就是记不起来了 基本上,我想为编程语言创建自己的语法。例如,此代码: WRITE OUT 'Hello World!' NEW LINE 将转换为以下Java代码: System.out.print("Hello World!"); System.out.println(); 我怎样才能做到这一点?有办法吗?Olá 有一些技术和适当的算法可以做到这一点。 搜索“编译器技术”和“解释器模式” 最初的方法可以是基本模式解释器。 假设简单
WRITE OUT 'Hello World!'
NEW LINE
将转换为以下Java代码:
System.out.print("Hello World!");
System.out.println();
我怎样才能做到这一点?有办法吗?Olá
有一些技术和适当的算法可以做到这一点。
搜索“编译器技术”和“解释器模式”
最初的方法可以是基本模式解释器。
假设简单的句子和每行只有一句话,您可以逐行读取输入文件并搜索定义的模式(正则表达式)。
模式用您发明的语言描述命令的结构。
如果你找到了匹配项,那么你就进行翻译
特别是,我们使用c中的regex.h库来执行正则表达式搜索。
当然,regex在java中也可用
例如,newline
匹配模式“*新+行*”
- *表示前面的字符出现0次或更多次
- +表示前面的字符出现1次或多次
- 因此,此模式可以将命令
与单词之间的任意空格相匹配“新行”
写下“你好,世界!”代码>匹配模式“写出”([[:print:]]*)”
- 或者如果您想允许空格
“*WRITE+OUT+”([[:print:][]*)”*“
- [[:print:]表示:匹配一个可打印字符(例如“a”或“Z”或“0”或“+”)
- 因此,[[:print:][]*匹配0、1或更多可打印字符的序列
如果输入文件中的一行与某个命令的模式匹配,则可以进行翻译,但在大多数情况下,您需要先检索一些信息,
写出来后的任意文本。这就是为什么需要在[[:print:][]*周围加括号的原因。这将向执行搜索的函数指示您希望检索模式的特定部分
一个很好的巧合是,我最近帮助一位朋友完成了一个大学项目,类似于你想解决的问题:一个从c到basic的翻译。我重用了这些代码,为您做了一个示例
我测试了代码,它运行正常。
它可以翻译为:
- 写出“一些文字”
- 写出变量
- 新线
#包括
#包括
#包括
#包括
#定义STR_SHORT 100
#定义大小为10的匹配项
/**************************************************************
返回匹配的字符串
**************************************************************/
char*GetExp(char*源、char*目标、regmatch\u t匹配){
//Source搜索的字符串
//目标将包含匹配的字符串
//匹配传递给regexec的向量的一个元素
int Length=Matches.rm_eo-Matches.rm_so;
strncpy(目的地、来源+Matches.rm_so、长度);
目的地[长度]=0;
返回目的地;
}
/**************************************************************
主要
**************************************************************/
int main(int argc,char*argv[]){
//用法
如果(argc==1){
printf(“用法:\n”);
printf(“解释器源文件”);
printf(“\n”);
printf(“实现一个非常基本的解释器\n”);
返回0;
}
//打开源文件
文件*源文件;
if((SourceFile=fopen(argv[1],“r”))==NULL)
返回1;
//此变量用于获取与模式匹配的字符串
//匹配[0]->正在搜索的整个字符串
//匹配[1]->第一个括号
//匹配[2]->第二个括号
regmatch_t Matches[匹配大小];
字符匹配STR[STR_SHORT];
//新行的正则表达式
regex_t regex_NewLine;
regcomp(&Regex_新行,“*新+行*”,regu扩展);
//用于写出“某些文本”的正则表达式
regex_t regex_WriteOutStr;
regcomp(&Regex_WriteOutStr,“*WRITE+OUT+”([[:print:][]*)”*”,regu扩展);
//写入变量的正则表达式
regex_t regex_WriteOutVar;
regcomp(&Regex_WriteOutVar,“*WRITE+OUT+([[u[:alpha:]][:alnum:]]*])*”,regu扩展);
//空行的正则表达式'
regex_t regex_EmptyLine;
regcomp(&Regex_-EmptyLine,“^([:space:]+)$”,REG_-EXTENDED);
//现在我们逐行读取文件
字符缓冲区[STR_SHORT];
while(fgets(Buffer,STR_SHORT,SourceFile)!=NULL){
//printf(“%s”,缓冲区);
//空线路短路
if(regexec(&Regex_EmptyLine,Buffer,MATCHES_SIZE,MATCHES,0)=0){
printf(“\n”);
继续;
}
//新线
if(regexec(&Regex_换行符、缓冲区、匹配项、大小、匹配项、0)==0){
printf(“System.out.println();\n”);
继续;
}
//写出“一些文字”
if(regexec(&Regex_WriteOutStr,Buffer,MATCHES_SIZE,MATCHES,0)=0){
printf(“System.out.print(\“%s\”);\n”,GetExp(Buffer,MatchedStr,Matches[1]);
继续;
}
//写出变量
//假设变量是字符串变量
if(regexec(&Regex_WriteOutVar,Buffer,MATCHES_SIZE,MATCHES,0)=0){
printf(“System.out.print(\“%s\”,%s);\n”,GetExp(Buffer,MatchedStr,MatchedStr[1]);
继续;
}
//未知命令
printf(“未知命令:%s”,缓冲区);
}
返回0;
}
Olá
有一些技术和适当的算法可以做到这一点。
s
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <string.h>
#define STR_SHORT 100
#define MATCHES_SIZE 10
/**************************************************************
Returns the string of a match
**************************************************************/
char * GetExp(char *Source, char *Destination, regmatch_t Matches) {
//Source The string that was searched
//Destination Will contains the matched string
//Matches One element of the vector passed to regexec
int Length = Matches.rm_eo - Matches.rm_so;
strncpy(Destination, Source+Matches.rm_so, Length);
Destination[Length]=0;
return Destination;
}
/**************************************************************
MAIN
**************************************************************/
int main(int argc, char *argv[]) {
//Usage
if (argc==1) {
printf("Usage:\n");
printf("interpreter source_file\n");
printf("\n");
printf("Implements a very basic interpreter\n");
return 0;
}
//Open the source file
FILE *SourceFile;
if ( (SourceFile=fopen(argv[1], "r"))==NULL )
return 1;
//This variable is used to get the strings that matched the pattern
//Matches[0] -> the whole string being searched
//Matches[1] -> first parenthetical
//Matches[2] -> second parenthetical
regmatch_t Matches[MATCHES_SIZE];
char MatchedStr[STR_SHORT];
//Regular expression for NEW LINE
regex_t Regex_NewLine;
regcomp(&Regex_NewLine, " *NEW +LINE *", REG_EXTENDED);
//Regular expression for WRITE OUT 'some text'
regex_t Regex_WriteOutStr;
regcomp(&Regex_WriteOutStr, " *WRITE +OUT +'([[:print:]]*)' *", REG_EXTENDED);
//Regular expresion for WRITE OUT variable
regex_t Regex_WriteOutVar;
regcomp(&Regex_WriteOutVar, " *WRITE +OUT +([_[:alpha:]][[:alnum:]]*) *", REG_EXTENDED);
//Regular expression for an empty line'
regex_t Regex_EmptyLine;
regcomp(&Regex_EmptyLine, "^([[:space:]]+)$", REG_EXTENDED);
//Now we read the file line by line
char Buffer[STR_SHORT];
while( fgets(Buffer, STR_SHORT, SourceFile)!=NULL ) {
//printf("%s", Buffer);
//Shorcut for an empty line
if ( regexec(&Regex_EmptyLine, Buffer, MATCHES_SIZE, Matches, 0)==0 ) {
printf("\n");
continue;
}
//NEW LINE
if ( regexec(&Regex_NewLine, Buffer, MATCHES_SIZE, Matches, 0)==0 ) {
printf("System.out.println();\n");
continue;
}
//WRITE OUT 'some text'
if ( regexec(&Regex_WriteOutStr, Buffer, MATCHES_SIZE, Matches, 0)==0 ) {
printf("System.out.print(\"%s\");\n", GetExp(Buffer, MatchedStr, Matches[1]));
continue;
}
//WRITE OUT variable
//Assumes variable is a string variable
if ( regexec(&Regex_WriteOutVar, Buffer, MATCHES_SIZE, Matches, 0)==0 ) {
printf("System.out.print(\"%%s\", %s);\n", GetExp(Buffer, MatchedStr, Matches[1]));
continue;
}
//Unknown command
printf("Unknown command: %s", Buffer);
}
return 0;
}