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;

}